Für größte Element kleiner als K in einem BST

stimmen
17

Bei einem binären Suchbaum und eine ganze Zahl K, würde Ich mag das größte Element finden weniger als K.

In dem unten stehenden Baum,

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

      10

  5       12

2   8   11  14

Ich versuchte, die unten Logik. Aber gibt es einen besseren Weg, dies zu tun?

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;
}
Veröffentlicht am 13/06/2011 um 19:22
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
1

Ich schlage vor , dass Sie durch den Code in der lokalen Umsetzung gehen Set :: upper_bound zur Orientierung. Dies ist nicht die Lösung für Ihr genaues Problem, aber ganz in der Nähe.

Im Allgemeinen im wirklichen Leben, die meisten dieser Probleme müssen nicht in Ihrem eigenen Code zu lösen. STL für Sie viele gemeinsame Aufgaben tun. Es ist nützlich zu wissen, wie sie natürlich zu lösen, damit Sie den Test.

Beantwortet am 13/06/2011 um 19:29
quelle vom benutzer

stimmen
3

Ich glaube , dass Standard - Bibliothek Einrichtungen in Verwendung. Somit verwendet meine Lösung 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;
}
Beantwortet am 13/06/2011 um 19:33
quelle vom benutzer

stimmen
19

Das ist O (log n), die das Minimum ist. Sie können jedoch die Effizienz verbessern und die Beseitigung der Möglichkeit der Stapelüberlauf (tada!) Durch die Beseitigung Endrekursion, drehen diese in eine Schleife (was die Hauptsache diese Interviewern kümmern uns um zu sein scheint). Auch dann , wenn der Code nicht, wenn der Baum negative Zahlen enthält ... , wenn Sie meinen nicht-negative ganze Zahlen, sollten Sie sagen so, aber wenn der Interviewer sagt nur „ganze Zahlen“ , dann müssen Sie etwas anderen Code und eine andere API. (Sie könnten die gleiche Funktion Unterschrift halten , aber das Rück K statt -1 bei einem Fehler.)

BTW, da dieses eine Interview-Frage, deren Umsetzung durch eine Bibliotheksfunktion aufrufen meisten Interviewern würde sagen, dass Sie ein smartass sind oder fehlen den Punkt oder wissen nicht, wie es zu lösen. Verwirren Sie nicht mit so etwas um, nur um zu arbeiten, was Sie wissen, dass der Interviewer will.

Hier ist eine Implementierung:

// 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;
}
Beantwortet am 13/06/2011 um 20:25
quelle vom benutzer

stimmen
5

Ich denke, die Idee ist, den letzten Knoten, nach dem Sie auf den rechten Teilbaum bewegen aufzunehmen. Daher wird der Code (wurde aktualisiert)

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)
}
Beantwortet am 14/06/2011 um 03:06
quelle vom benutzer

stimmen
1

Was die erste Antwort gesagt, und hier ist die Logik hinter warum kann es nicht besser als O (log n). Sie suchen die größte Zahl kleiner als K. Die ganz in der Nähe ist BST-Suche zu rufen / bekommen.

Obwohl Ihre ursprüngliche Algorithmus ziemlich gut aussieht, ich denke, das wäre schneller:

    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

    }
Beantwortet am 27/07/2011 um 11:11
quelle vom benutzer

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