permutace BST

hlasů
5

Vzhledem k tomu, pole celých čísel arr = [5,6,1].

Když jsme se postavit BST s tímto vstupem ve stejném pořadí, budeme mít „5“ jako root, „6“ jako správnou dítě a „1“, jak je opustil dítě.

Nyní, když je náš vstup změní na [5,1,6], stále naší BST struktura bude totožný.

Takže vzhledem k tomu, pole celých čísel, jak najít řadu různých permutací vstupního pole, které vyústí v identické BST jako BST vytvořené na původní pole pořadí?

Položena 09/11/2009 v 16:07
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
-1

Dalo by se to obráceně: Vzhledem k tomu, BST, vyjmenovat všechny pole celých čísel, která by mohla přinést tuto BST ...

Nemohl jste (pomocí Nedeterminismus ...)

  1. vyzařují kořen a přidat ji do emitovaného sadě.
  2. nedeterministicky zvolit položku ze stromu, který není v emitovaného sadě, ale jehož rodič je, a přidat ji do emitovaného sady a vydávat ji.
  3. opakovat 2, dokud všechny emitovány.

Nedeterministické chování vám poskytne všechny takové pole. Pak můžete počítat.

Odpovězeno 09/11/2009 v 16:15
zdroj uživatelem

hlasů
9

Váš dotaz je ekvivalentní k otázce spočítáním topologických orderings pro danou BST.

Například pro BST

  10
 /  \
5   20
 \7 | \
    15 30

množina topologické orderings lze počítat ručně takto: 10 spustí každé objednávce. Počet topologických orderings pro podstromu počínaje 20 je dva: (20, 15, 30) a (20, 30, 15). Podstrom počínaje 5 má pouze jedno uspořádání: (5, 7). Tyto dvě sekvence mohou být prokládány v libovolným způsobem, což vede k 2 x 10 interleavings, tak produkovat dvacet vstupy, které produkují stejné BST. Prvních 10 jsou vyjmenovány níže pro případ, (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

Pouzdra (20, 30, 15) je analogický --- lze zjistit, že každý z těchto vstupů produkuje stejný BST.

Tento příklad také poskytuje rekurzivní pravidla pro výpočet počtu orderings. U listu, je číslo 1 pro non-koncový uzel s jedním dítětem, číslo se rovná počtu topologických orderings pro dítě. Pro non-listu uzlu se dvěma dětmi s velikostí podstromu | l | a | R |. Oba mají L a R orderings, resp počet se rovná

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

Kde INT je počet možných interleavings z | l | a | R | Prvky. To lze snadno vypočítat (| L | + | R |)! / (| L |! X | R |!). Ve výše uvedeném příkladu, dostaneme následující rekurzivní výpočet:

  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

To řeší problém.

Poznámka: Toto řešení předpokládá, že všechny uzly v BST mají různé klíče.

Odpovězeno 10/11/2009 v 18:34
zdroj uživatelem

hlasů
1

Díky za vysvětlení antti.huima! To mi pomohlo pochopit. Zde jsou některé 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;
}
Odpovězeno 06/03/2013 v 03:59
zdroj uživatelem

hlasů
0

Na tuto otázku lze snadno vyřešit, pokud máte jen málo informací o rekurze, permutace a kombinace, a obeznámenost s strom binárního vyhledávání (samozřejmě).

Nejprve si vybudovat binární vyhledávací strom s danou sekvencí. Také můžete provádět stejné operace v poli, ale stromové vizualizace by malovat dobrý obraz.

Pro dané sekvence arr [1..n], 1. prvek by zůstat na místě, jak je to v daném poli a potřebuje pouze uspořádání třeba uvést v arr [2..n].

Převzít:

kabelky1 = počet prvků v arr [2..n], které jsou méně než arr [0].

a,

bag2 = počet prvků v arr [2..n], které jsou větší než arr [0].

Vzhledem k tomu, permutace prvků v kabelky1 v posloupnosti nebudou představovat konflikt s čísly přítomných v bag2 za vytvoření binární vyhledávací strom, jeden může začít začít výpočtu odpověď od nástupu kabelky1 prvky z (n-1) prvků permutate a pak se zbytek ((n-1) - kabelky1) = bag2 prvky mohou být umístěny v 1 způsobem teprve nyní . Řazení prvků v kabelky1 by měly být stejné, a také pro bag2 prvků v sekvenci.

Vzhledem k tomu, každé podstromu binárního vyhledávacího stromu musí být BST. Podobný postup by byl provozován na každém uzlu a znásobit místní odpověď na uzlu až po konečnou odpověď.

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;
}
Odpovězeno 12/08/2017 v 08:52
zdroj uživatelem

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