permutaties van BST

stemmen
5

Gegeven een reeks integers arr = [5,6,1].

Wanneer we een BST construct met deze ingang in dezelfde volgorde, zullen we 5 hebben als root, 6 als rechterkind en 1 als de linker kind.

Indien nu onze ingang wordt gewijzigd in [5,1,6], nog steeds onze BST structuur identiek zijn.

Dus gegeven een reeks integers, hoe de verschillende permutaties van de invoerarray die resulteert in de identieke BST als BST gevormd op de oorspronkelijke array bestellen?

De vraag is gesteld op 09/11/2009 om 16:07
bron van user
In andere talen...                            


4 antwoorden

stemmen
-1

U kunt dit achteruit doen: Gegeven een BST, inventariseren alle arrays van integers waarop deze BST kan opleveren ...

Kon je (met behulp van nondeterminisme ...)

  1. uitstoten wortel en voeg deze toe aan de uitgezonden set.
  2. nondeterministically kiest u een item uit de boom die niet in de uitgezonden set, maar waarvan de moedermaatschappij is, en voeg deze toe aan de uitgezonden set en geven het.
  3. 2 herhalen totdat alle uitgezonden.

De nondeterminisme zal u al deze arrays te geven. Dan kunt u ze tellen.

antwoordde op 09/11/2009 om 16:15
bron van user

stemmen
9

Uw vraag is gelijk aan de kwestie van tellen van het aantal topologische ordeningen voor de gegeven BST.

Bijvoorbeeld, de BST

  10
 /  \
5   20
 \7 | \
    15 30

de set van topologische ordeningen kan worden met de hand geteld als volgt uit: 10 begint elke bestelling. Het aantal topologische ordeningen voor de deelboom ab 20 twee: (20, 15, 30) en (20, 30, 15). De substructuur te beginnen met 5 heeft slechts één bestelling: (5, 7). Beide sequentie kan worden verweven op een willekeurige manier, wat leidt tot 2 x 10 schutbladen, waardoor aldus twintig ingangen die dezelfde BST produceren. De eerste 10 zijn hieronder opgesomd voor de behuizing (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

De behuizing (20, 30, 15) is analoog --- u controleren of elk van de volgende ingangen heeft dezelfde BST.

Dit voorbeeld verschaft ook een recursieve regel om het aantal ordeningen berekenen. Voor een blad, het nummer is 1. Voor een niet-leaf node met een kind, is het aantal gelijk aan het aantal topologische ordeningen voor het kind. Voor een niet-leaf node met twee kinderen met subtree maten | L | en | R |., beide met l en r ordeningen, respectievelijk, het getal gelijk aan

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

Waar INT is het aantal mogelijke schutbladen van | L | en | R | elementen. Dit kan gemakkelijk worden berekend door (| L | + | R |)! / (| L |! X | R |!). In het bovenstaande voorbeeld, krijgen we de volgende recursieve berekening:

  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

Dit lost het probleem op.

Let op: deze oplossing gaat ervan uit dat alle knooppunten in het BST hebben verschillende sleutels.

antwoordde op 10/11/2009 om 18:34
bron van user

stemmen
1

Bedankt voor de uitleg antti.huima! Dit hielp me begrijpen. Hier is een aantal 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;
}
antwoordde op 06/03/2013 om 03:59
bron van user

stemmen
0

Deze vraag kan gemakkelijk worden opgelost als je weinig kennis van recursie, permutatie en combinaties, en vertrouwdheid met Binary Search Tree (uiteraard).

Eerst moet je bouwen van een binaire zoekboom met de gegeven volgorde. U kunt ook dezelfde bewerking uit te voeren in de reeks, maar boom-visualisatie zou een goed beeld te schetsen.

Voor bepaalde volgorde arr [1..n], zou 1 element blijven zitten als in de gegeven array en enige regeling nodig heeft arr [2..n] worden gebracht.

Uitgaan van:

Koeltas1 = aantal elementen in arr [2..n] die minder dan arr [0] aan.

en,

bag2 = aantal elementen in arr [2..n] die groter is dan arr [0] aan.

Aangezien de permutatie van elementen in Koeltas1 in de sequentie een conflict met de in de bag2 getallen geen veiligheidsrisico vormt onder vorming van een binaire zoekboom, kan men beginnen starten met het berekenen het antwoord van plukken Koeltas1 elementen van (n-1) elementen permuteren en vervolgens rusten ((n-1) - Koeltas1) = bag2 elementen in 1 weg worden gebracht nu . Ordening van elementen in Koeltas1 moet hetzelfde en ook voor bag2 elementen in de sequentie moet zijn.

Aangezien elke deelboom van een binaire zoekboom moet een BST zijn. Een soortgelijk proces worden uitgevoerd op elk knooppunt en vermenigvuldig het lokale antwoord op het knooppunt uiteindelijke antwoord.

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;
}
antwoordde op 12/08/2017 om 08:52
bron van user

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