Aby znaleźć Największy element mniejszy niż K w BST

głosy
17

Biorąc pod uwagę binarne drzewo wyszukiwania i liczba całkowita K, chciałbym znaleźć największą elementu mniej niż K.

W poniższym drzewie,

for K = 13, result = 12
for K = 10, result = 8
for K = 1 (or) 2, result = -1

      10

  5       12

2   8   11  14

Próbowałem poniżej logikę. Ale czy jest jakiś lepszy sposób to zrobić?

int findNum(node* node, int K)
{
        if(node == NULL)
        {
                return -1;
        }
        else if(K <= node->data)
        {
                return findNum(node->left,K);
        }
        else if(K > node->data)
        {
                int t = findNum(node->right,K);
                return t > node->data ? t : node->data;
        }

        return -1;
}
Utwórz 13/06/2011 o 19:22
źródło użytkownik
W innych językach...                            


5 odpowiedzi

głosy
1

I sugerują, że idziesz przez kod w lokalnej wykonania zestawu :: UPPER_BOUND orientacyjna. To nie jest rozwiązaniem do dokładnego problemu, ale bardzo blisko.

W ogóle w życiu, większość z tych problemów nie muszą być rozwiązane w swoim własnym kodzie. STL można zrobić wiele wspólnych zadań dla ciebie. To warto wiedzieć, jak je rozwiązać oczywiście stąd test.

Odpowiedział 13/06/2011 o 19:29
źródło użytkownik

głosy
3

Wierzę w użyciu standardowych bibliotek. Tak więc moje rozwiązanie wykorzystuje std::set. :-)

int largest_num_smaller_than(std::set<int> const& set, int num)
{
    std::set<int>::const_iterator lb(set.lower_bound(num));
    return lb == set.begin() ? -1 : *--lb;
}
Odpowiedział 13/06/2011 o 19:33
źródło użytkownik

głosy
19

To O (log n), który jest minimalna. Można jednak poprawić skuteczność (co wydaje się być najważniejsze, te wywiady obchodzi) i wyeliminować możliwość przepełnienia stosu (Tada!) Poprzez wyeliminowanie ogon rekursji, zamieniając to w pętli. Ponadto, Twój kod nie działa, jeśli drzewo zawiera liczb ujemnych ... jeśli masz na myśli nieujemne liczby całkowite, należy powiedzieć tak, ale jeśli ankieter tylko, że „całkowite” to trzeba nieco inny kod i inny API. (Można zachować tę samą funkcję podpisu ale zamiast wrócić K -1 w przypadku awarii).

BTW, ponieważ jest to pytanie wywiad, wdrożenie go przez wywołanie funkcji biblioteki powie większość ankieterów, że jesteś smartass lub brakuje punktu lub nie wiesz jak go rozwiązać. Nie należy poeksperymentować z tego rodzaju rzeczy, po prostu dostać się do pracy, co wiesz ankieter chce.

Oto realizacja:

// Return the greatest int < K in tree, or K if none.
int findNum (Node* tree, int K)
{
    int val = K;

    while( tree )
        if( tree->data >= K )
            tree = tree->left;
        else{
            val = tree->data; 
            tree = tree->right;
        }

    return val;
}
Odpowiedział 13/06/2011 o 20:25
źródło użytkownik

głosy
5

Myślę, że pomysł jest, aby nagrać ostatni węzeł, po którym przesuwa się w prawo poddrzewie. Dlatego kod zostanie (został zaktualizowany)

int findNum (Node *node, int K)
{
    Node* last_right_move = NULL;

    while (node)
    {
        if (K<=node->data)
            node = node->left;
        else
        {
            last_right_move = node;
            node = node->right;
        }
    }

    if (last_right_move)
        return last_right_move->data;
    else
        return NOT_FOUND;  // defined previously. (-1 may conflict with negative number)
}
Odpowiedział 14/06/2011 o 03:06
źródło użytkownik

głosy
1

Co pierwsza odpowiedź powiedział, a tu jest logika, dlaczego nie można dostać lepsze niż O (log n). Szukasz największej liczbie mniejszej niż K. Jest to dość blisko do wywoływania BST-search / dostać.

Chociaż oryginalny algorytm wygląda całkiem dobrze, myślę, że to będzie szybciej:

    int findNum (node root, int K) {
        if(root == null) return -1;

        if(K > root.val) { 
           if(root.right != null) return findNum(root.right, K);               
           else return root.val; 
        }

        return findNum(root.left, K); //look in left subtree

    }
Odpowiedział 27/07/2011 o 11:11
źródło użytkownik

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