παραλλαγές της BST

ψήφοι
5

Δεδομένης μια σειρά ακεραίων arr = [5,6,1].

Όταν κατασκευάζουμε ένα BST με αυτήν την είσοδο με την ίδια σειρά, θα έχουμε «5» ως root, «6», όπως το δικαίωμα του παιδιού και το «1» ως αριστερό παιδί.

Τώρα, αν εισόδου μας αλλάζει σε [5,1,6], εξακολουθούν δομή BST μας θα είναι το ίδιο.

Έτσι, δίνεται ένας πίνακας ακεραίων, πώς να βρείτε τον αριθμό των διαφορετικών συνδυασμών του πίνακα εισόδου που οδηγεί στην όμοια BST ως BST που σχηματίζεται από την αρχική παραγγελία σειρά;

Δημοσιεύθηκε 09/11/2009 στις 16:07
πηγή χρήστη
Σε άλλες γλώσσες...                            


4 απαντήσεις

ψήφοι
-1

Θα μπορούσατε να το κάνετε αυτό προς τα πίσω: Δεδομένου ενός BST, απαριθμήσει όλες τις συστοιχίες των ακέραιων αριθμών που μπορεί να δώσει αυτό το BST ...

Δεν θα μπορούσε να σας (χρησιμοποιώντας nondeterminism ...)

  1. εκπέμπουν ρίζα και προσθέστε το στο εκπέμπεται σύνολο.
  2. nondeterministically επιλέξετε ένα στοιχείο από το δέντρο που δεν είναι στην εκπέμπεται σύνολο, αλλά των οποίων η μητρική είναι, και προσθέστε το στο εκπέμπεται σύνολο και εκπέμπουν αυτό.
  3. επαναλάβετε 2 έως ότου όλα εκπέμπεται.

Η nondeterminism θα σας δώσει όλες αυτές τις σειρές. Στη συνέχεια, μπορείτε να τα μετρήσω.

Απαντήθηκε 09/11/2009 στις 16:15
πηγή χρήστη

ψήφοι
9

Η ερώτησή σας είναι ισοδύναμο με το ερώτημα της μετρώντας τον αριθμό των τοπογραφικών orderings για το συγκεκριμένο BST.

Για παράδειγμα, για την BST

  10
 /  \
5   20
 \7 | \
    15 30

το σύνολο των τοπογραφικών orderings μπορεί να μετρηθεί με το χέρι σαν αυτό: 10 ξεκινά κάθε παραγγελία. Ο αριθμός των τοπολογικών orderings για την υποδένδρο ξεκινώντας με 20 είναι δύο: (20, 15, 30) και (20, 30, 15). Το υποδένδρο ξεκινώντας με 5 έχει μόνο ένα παραγγελίας: (5, 7). Αυτά τα δύο αλληλουχία μπορεί να παρεμβληθούν σε ένα αυθαίρετο τρόπο, οδηγώντας σε 2 χ 10 interleavings, παράγοντας έτσι είκοσι εισόδους οι οποίες παράγουν το ίδιο BST. Το πρώτο 10 απαριθμούνται παρακάτω για την περίπτωση (20, 15, 30):

 10 5 7 20 15 30
 10 5 20 7 15 30
 10 5 20 15 7 30
 10 5 20 15 30 7
 10 20 5 7 15 30
 10 20 5 15 7 30
 10 20 5 15 30 7
 10 20 15 5 7 30
 10 20 15 5 30 7
 10 20 15 30 5 7

Η υπόθεση (20, 30, 15) είναι ανάλογη --- μπορείτε να ελέγξετε ότι κάθε μία από τις ακόλουθες εισόδους παράγει το ίδιο BST.

Το παράδειγμα αυτό παρέχει επίσης ένα αναδρομικό κανόνα για τον υπολογισμό του αριθμού των orderings. Για ένα φύλλο, ο αριθμός είναι 1. Για ένα κόμβο χωρίς φύλλο με ένα παιδί, ο αριθμός ισούται με τον αριθμό των τοπογραφικών orderings για το παιδί. Για έναν κόμβο μη φύλλου με δύο παιδιά με μεγέθη υποδένδρο | L | και | R |., αμφότερα έχοντας L και R orderings, αντίστοιχα, ο αριθμός ισούται με

  l x r x INT(|L|, |R|)

Σε περίπτωση που INT είναι ο αριθμός των πιθανών interleavings της | L | και | R | στοιχεία. Αυτό μπορεί εύκολα να υπολογιστεί από (| L | + | R |)! / (| L |! X | R |!). Για το παραπάνω παράδειγμα, παίρνουμε την ακόλουθη επαναληπτικού υπολογισμού:

  Ord(15) = 1
  Ord(30) = 1
  Ord(20) = 1 x 1 x INT(1, 1) = 2  ; INT(1, 1) = 2! / 1 = 2
  Ord(7) = 1
  Ord(5) = 1
  Ord(10) = 1 x 2 x INT(2, 3) = 2 x 5! / (2! x 3!) = 2 x 120 / 12 = 2 x 10 = 20

Αυτό λύνει το πρόβλημα.

Σημείωση: αυτή η λύση προϋποθέτει ότι όλοι οι κόμβοι στο BST έχουν διαφορετικά κλειδιά.

Απαντήθηκε 10/11/2009 στις 18:34
πηγή χρήστη

ψήφοι
1

Ευχαριστώ για την antti.huima εξήγηση! Αυτό με βοήθησε να καταλάβω. Εδώ είναι μερικές C ++:

#include <vector>
#include <iostream>

using namespace std;

int factorial(int x) {
  return (x <= 1) ? 1 : x * factorial(x - 1);
}

int f(int a, int b) {
  return factorial(a + b) / (factorial(a) * factorial(b));
}

template <typename T>
int n(vector<T>& P) {
  if (P.size() <= 1) return 1;
  vector<T> L, R;
  for (int i = 1; i < P.size(); i++) {
    if (P[i] < P[0])
      L.push_back(P[i]);
    else
      R.push_back(P[i]);
  }
  return n(L) * n(R) * f(L.size(), R.size());
}

int main(int argc, char *argv[]) {
  vector<int> a = { 10, 5, 7, 20, 15, 30 };
  cout << n(a) << endl;
  return 0;
}
Απαντήθηκε 06/03/2013 στις 03:59
πηγή χρήστη

ψήφοι
0

Αυτό το ζήτημα μπορεί να λυθεί εύκολα αν έχετε λίγη γνώση της αναδρομής, μετάθεση και συνδυασμούς, και την εξοικείωση με Binary Search Tree (προφανώς).

Πρώτα δημιουργείτε ένα δυαδικό δέντρο αναζήτησης με τη συγκεκριμένη σειρά. Μπορείτε επίσης να εκτελέσετε την ίδια λειτουργία με την σειρά, αλλά δέντρο-οπτικοποίηση θα δίνουν μια καλή εικόνα.

Για δεδομένη αλληλουχία arr [1..n], 1ο στοιχείο θα μένουν στη θέση τους, όπως είναι στη δεδομένη συστοιχία και μόνο διάταξη πρέπει να προσαρμοστεί σε ARR [2..n].

Υποθέτω:

τσάντες1 = αριθμός των στοιχείων σε ARR [2..n] οι οποίες είναι μικρότερες από ό, τι arr [0].

και,

BAG2 = αριθμός των στοιχείων σε ARR [2..n] οι οποίες είναι μεγαλύτερες από arr [0].

Δεδομένου ότι η μετάθεση των στοιχείων στο τσάντες1 με τη σειρά που δεν θα θέτουν σε σύγκρουση με τους αριθμούς που υπάρχουν στο BAG2 ενώ σχηματίζουν ένα δυαδικό δέντρο αναζήτησης, μπορεί κανείς να ξεκινήσει να ξεκινήσει τον υπολογισμό του απάντηση επιλέγοντας στοιχεία τσάντες1 από (n-1) στοιχεία permutate και στη συνέχεια να ξεκουραστεί ((n-1) - τσάντες1) = στοιχεία BAG2 μπορούν να τοποθετηθούν σε 1 τρόπο μόλις τώρα . Ταξινόμηση των στοιχείων σε τσάντες1 πρέπει θα πρέπει να είναι ίδια και παρομοίως για τα στοιχεία BAG2 στην ακολουθία.

Από κάθε υποδέντρο ενός δυαδικού δέντρου αναζήτησης πρέπει να είναι BST. Παρόμοια διαδικασία θα πρέπει να λειτουργεί σε κάθε κόμβο και να πολλαπλασιάσει την τοπική απάντηση για τον κόμβο στην τελική απάντηση.

int ans = 1;
int size[1000000] = {0};

// calculate the size of tree and its subtrees before running function "fun" given below.
int calSize(struct node* root){
     if(root == NULL)
          return 0;

     int l = calSize(root->left);
     int r = calSize(root -> right);
     size[root->val] = l+r+1;
     return size[root->val]; 
}

void fun(struct node* root){
     if(root == NULL)
         return;

     int n = size[root->val];
     if(root->left){
         ans *= nCr(n-1, size[root->left]);
         ans *= 1; // (Just to understand that there is now only 1 way 
                   //to distribute the rest (n-1)-size of root->left)
     }

     fun(root->left);
     fun(root->right); 
}

int main(){
     struct node* root;

     //construct tree
     //and send the root to function "fun"

     fun(root);

     cout<<ans<<endl;
     return 0;
}
Απαντήθηκε 12/08/2017 στις 08:52
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more