permutasjoner av BST

stemmer
6

Gitt en matrise av heltall arr = [5,6,1].

Når vi konstruere en BST med denne inngangen i samme bestilling, vil vi ha 5 som root, 6 som retten barnet og 1 som venstre barn.

Nå hvis våre innspill er endret til [5,1,6], fortsatt vår BST strukturen vil være identiske.

Så gitt en rekke tall, hvordan finne antall forskjellige permutasjoner av input array som resulterer i identiske BST som BST dannet på den opprinnelige matrisen orden?

Publisert på 09/11/2009 klokken 15:07
kilden bruker
På andre språk...                            


4 svar

stemmer
-1

Du kan gjøre dette baklengs: Gitt en BST, nummerere alle matriser av tall som kan gi denne BST ...

Kunne ikke du (med nondeterminism ...)

  1. avgir rot og legge det til det utsendte settet.
  2. nondeterministically velge et element fra treet som ikke er i den slippes sett, men hvis foreldrene er, og legge det til utsendt sett og avgir den.
  3. gjenta 2 inntil alt slippes ut.

Den nondeterminism vil gi deg alle slike arrays. Deretter kan du telle dem.

Svarte 09/11/2009 kl. 15:15
kilden bruker

stemmer
10

Spørsmålet ditt er tilsvarende til spørsmålet om å telle antall topologiske orde for gitt BST.

For eksempel for BST

  10
 /  \
5   20
 \7 | \
    15 30

settet av topologiske orde kan telles for hånd slik: 10 starter hver bestilling. Antallet topologiske orde for undertreet med utgangspunkt i 20 er to: (20, 15, 30) og (20, 30, 15). Undertreet som starter med 5 har bare ett rekkefølge: (5, 7). Disse to sekvensen kan innfelles i en vilkårlig måte, som fører til 2 x 10 interleavings, og dermed produsere tyve innganger som produserer den samme BST. Den første 10 er oppregnet nedenfor for en kasse (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

Saken (20, 30, 15) er analog --- man kan kontrollere at en hvilken som helst av de følgende innganger frembringer den samme BST.

Dette eksempelet gir også en rekursiv regel for å beregne antall den orden. For et blad, er nummer 1. For en ikke-bladnode med ett barn, er lik tallet til antall topologiske orde for barnet. For en ikke-blad node med to barn med undertreet størrelser | L | og | R |., begge har L og R orde, resp, er lik antallet til

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

Hvor INT er antall mulige interleavings av | L | og | R | elementer. Dette kan beregnes enkelt ved (| L | + | R |)! / (| L |! X | R |!). For eksempelet ovenfor, får vi følgende rekursive beregningen:

  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

Dette løser problemet.

Merk: Denne løsningen forutsetter at alle noder i BST har forskjellige nøkler.

Svarte 10/11/2009 kl. 17:34
kilden bruker

stemmer
1

Takk for forklaringen antti.huima! Dette hjalp meg å forstå. Her er noen 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;
}
Svarte 06/03/2013 kl. 02:59
kilden bruker

stemmer
0

Dette spørsmålet kan løses enkelt hvis du har lite kjennskap til rekursjon, permutasjon og kombinasjoner, og kjennskap til binært søketre (selvsagt).

Først bygge et binært søketre med den gitte sekvensen. Du kan også utføre den samme operasjonen i rekken, men tre-visualisering ville male et godt bilde.

For gitt sekvens arr [1..n], ville første element holder seg på plass slik det er i den gitte matrisen og bare ordning må bringes i arr [2..n].

Anta:

bag1 = antallet elementer i arr [2..n] som er mindre enn arr [0].

og,

bag2 = antallet elementer i arr [2..n] som er større enn arr [0].

Siden den permutasjon av elementer i bag1 i sekvensen ikke vil utgjøre noen konflikt med tall som er tilstede i den bag2 under dannelse av et binært søk treet, kan man begynne å begynne å beregne svaret ved å plukke bag1 elementer ut fra (n-1) elementer å permutate og deretter hvile ((n-1) - bag1) = bag2 elementer kan plasseres på en måte som bare nå . Sortering av elementer i bag1 bør være like, og likeledes for bag2 elementer i rekkefølge.

Siden hver treet av et binært søketre må være en BST. Lignende prosess vil bli operert på hver node og multiplisere det lokale svaret for noden til endelig svar.

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;
}
Svarte 12/08/2017 kl. 08:52
kilden bruker

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