Permutationen von BST

stimmen
5

Gegeben ein Array von ganzen Zahlen arr = [5,6,1].

Wenn wir ein BST mit diesem Eingang in der gleichen Reihenfolge konstruieren, werden wir „5“ als Wurzel, „6“ als das rechte Kind und „1“ als linkes Kind haben.

Nun, wenn unsere Eingabe in [5,1,6] geändert wird, immer noch unsere BST Struktur identisch sein.

Gegeben, so ein Array von ganzen Zahlen, wie die Anzahl der verschiedenen Permutationen des Eingangsfeldes zu finden, die als BST in der identischen BST führt auf der ursprünglichen Anordnung gebildet, um?

Veröffentlicht am 09/11/2009 um 16:07
quelle vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
-1

Man könnte dies rückwärts tun: Bei einem BST, aufzuzählen alle Arrays von ganzen Zahlen, die diese BST ergeben könnten ...

Könnten Sie nicht (mit Nicht-Determinismus ...)

  1. root emittieren und fügen sie dem emittierten set.
  2. nichtdeterministisch zu wählen, aus dem Baum ein Element, das nicht in der emittierten Menge ist, aber dessen Elternteil ist, und es in dem ausgesendeten Satz hinzufügen und emittiert.
  3. wiederholen 2, bis alle emittiert.

Die Nicht-Determinismus wird Ihnen alle diese Arrays. Dann können Sie sie zählen.

Beantwortet am 09/11/2009 um 16:15
quelle vom benutzer

stimmen
9

Ihre Frage ist gleichbedeutend mit der Frage nach der Anzahl der topologischen Anordnungen für die gegebene BST zu zählen.

Zum Beispiel für die BST

  10
 /  \
5   20
 \7 | \
    15 30

10 beginnt jede Bestellung: die Menge der topologischen Anordnungen kann von Hand wie folgt gezählt werden. Die Anzahl der topologische Anordnungen für den Teilbaum mit 20 beginnt, ist zwei (20, 15, 30) und (20, 30, 15). Der Teilbaum mit 5 ausgehend nur einer Reihenfolge: (5, 7). Diese zwei-Sequenz kann in beliebiger Weise verschachtelt werden, um 2 x 10 Verschachtelungen führende somit zwanzig Eingänge, welches die gleiche BST erzeugen. Die ersten 10 sind im folgenden für den Fall (20, 15, 30) aufgezählt:

 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

Der Fall ist (20, 30, 15) analog --- Sie können prüfen, ob eine der folgenden Eingaben die gleiche BST erzeugt.

Dieses Beispiel stellt auch eine rekursive Regel die Anzahl der Ordnungen zu berechnen. Für ein Blatt ist die Nummer 1 für einen Nicht-Blattknoten mit einem Kind, die Zahl der Anzahl der topologischen Anordnungen für das Kind ist gleich. Für einen Nicht-Blattknoten mit zwei Kindern mit Teilbaum Größen | L | und | R |., beide mit L und R Ordnungen bzw. die Anzahl gleich zu

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

Wo INT ist die Anzahl der möglichen Verschachtelungen von | L | und | R | Elemente. Dies kann leicht berechnet werden (| L | + | R |)! / (| L |! X | R |!). Für das obige Beispiel, erhalten wir die folgende rekursive Berechnung:

  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

Dies löst das Problem.

Hinweis: Diese Lösung setzt voraus, dass alle Knoten in der BST verschiedene Schlüssel haben.

Beantwortet am 10/11/2009 um 18:34
quelle vom benutzer

stimmen
1

Danke für die Erklärung antti.huima! Das half mir zu verstehen. Hier sind einige 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;
}
Beantwortet am 06/03/2013 um 03:59
quelle vom benutzer

stimmen
0

Diese Frage kann leicht gelöst werden, wenn Sie wenig Wissen über Rekursion, Permutation und Kombinationen haben, und die Vertrautheit mit binärem Suchbaum (offensichtlich).

Zuerst bauen Sie einen binären Suchbaum mit der angegebenen Reihenfolge. Sie können auch die gleiche Operation in der Anordnung, aber Baum Visualisierung ein gutes Bild malen würde durchführen.

Für gegebene Sequenz arr [1..n], würde 1. Element gesetzt bleiben, wie es in der gegebenen Array ist und nur Anordnung braucht in arr [2..n] gebracht werden.

Annehmen:

bag1 = Anzahl der Elemente in arr [2..n], die weniger als arr [0].

und,

bag2 = Anzahl der Elemente in arr [2..n], die größer als arr [0].

Da die Permutation der Elemente in bag1 in der Folge nicht zu einem Konflikt mit den Zahlen , die in der bag2 unter Bildung eines binären Suchbaums darstellen wird, kann man beginnen , beginnen die Antwort berechnet wird, indem Kommissionierung bag1 Elemente von (n-1) Elemente permutate und dann ruhen ((n-1) - bag1) = bag2 Elemente können erst jetzt in 1 so platziert werden . Reihenfolge der Elemente in bag1 sollten soll gleich und ebenfalls für bag2 Elemente in der Folge sein.

Da jeder Unterbaum eines binären Suchbaum hat ein BST sein. Ähnliche Verfahren auf jedem Knoten betrieben werden würden die lokale Antwort für den Knoten endgültige Antwort und ich vermehren.

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;
}
Beantwortet am 12/08/2017 um 08:52
quelle vom benutzer

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