Om grootste element kleiner is dan K vinden in een BST

stemmen
17

Gegeven een binaire zoekboom en een integer K, zou ik graag de grootste element minder dan K. vinden

In de onderstaande boom,

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

      10

  5       12

2   8   11  14

Ik probeerde de onderstaande logica. Maar is er een betere manier om dit te doen?

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;
}
De vraag is gesteld op 13/06/2011 om 19:22
bron van user
In andere talen...                            


5 antwoorden

stemmen
1

Ik stel voor dat je door de code in uw lokale implementatie van Set :: UPPER_BOUND voor begeleiding. Dit is niet de oplossing voor uw exacte probleem, maar heel dichtbij.

In het algemeen is in het echte leven, de meeste van deze problemen niet moeten worden opgelost in uw eigen code. STL kunnen veel voorkomende taken voor u doen. Het is handig om te weten hoe ze op te lossen natuurlijk, vandaar de test.

antwoordde op 13/06/2011 om 19:29
bron van user

stemmen
3

Ik geloof in het gebruik van standaard bibliotheek faciliteiten. Dus mijn oplossing maakt gebruik van 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;
}
antwoordde op 13/06/2011 om 19:33
bron van user

stemmen
19

Dat is O (log n), dat is het minimum. U kunt echter wel de efficiëntie te verbeteren (die lijkt te zijn het belangrijkste ding deze interviewers de zorg over zijn) en elimineren van de mogelijkheid van een stack overflow (Tada!) Door het elimineren van staartrecursie, draaien dit in een lus. Ook heeft uw code niet werkt als de boom negatieve getallen bevat ... als je bedoelt niet-negatieve gehele getallen, moet jij het zegt, maar als de interviewer zei gewoon "integers" dan moet je iets anders code en een andere API nodig. (U kunt dezelfde functie handtekening te houden, maar terugkeren K in plaats van -1 op defecten.)

BTW, want dit is een interview vraag, de uitvoering ervan door te bellen naar een functie uit de bibliotheek zou vertellen de meeste interviewers dat je een slimmerik of ontbreekt het punt of niet weten hoe het op te lossen. Do not mess rond met dat soort dingen, gewoon om te werken aan wat je weet de interviewer wil.

Hier is een implementatie:

// 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;
}
antwoordde op 13/06/2011 om 20:25
bron van user

stemmen
5

Ik denk dat het idee is hier om de laatste knoop, waarna u naar de rechter deelboom te nemen. Daarom wordt de code zal worden (is bijgewerkt)

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)
}
antwoordde op 14/06/2011 om 03:06
bron van user

stemmen
1

Wat het eerste antwoord gezegd, en hier is de logica achter waarom het niet beter dan O (log n) kunnen krijgen. U bent op zoek naar het grootste aantal kleiner is dan K. Dit is vrij dicht bij het roepen BST-search / krijgen.

Hoewel uw oorspronkelijke algoritme ziet er heel goed, ik denk dat dit zou sneller zijn:

    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

    }
antwoordde op 27/07/2011 om 11:11
bron van user

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