Pentru a găsi cel mai mare element mai mic decât K într-un BST

voturi
17

Având în vedere o căutare arbore binar și un număr întreg K, i-ar dori să găsească cel mai mare element mai puțin de K.

În arborele de mai jos,

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

      10

  5       12

2   8   11  14

Am încercat logica de mai jos. Dar există nici o modalitate mai bună de a face acest lucru?

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;
}
Întrebat 13/06/2011 la 19:22
sursa de către utilizator
În alte limbi...                            


5 răspunsuri

voturi
1

Vă sugerez să se plimbe prin codul în implementarea locală a stabilit :: UPPER_BOUND pentru orientare. Acest lucru nu este soluția la problema ta exactă, dar foarte aproape.

În general, în viața reală, cele mai multe dintre aceste probleme nu trebuie să fie rezolvate în propriul cod. STL pot face multe sarcini comune pentru tine. Este util să știi cum să le rezolve, desigur, prin urmare, testul.

Publicat 13/06/2011 la 19:29
sursa de către utilizator

voturi
3

Eu cred în utilizarea bibliotecii facilități standard. Astfel, soluția mea folosește 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;
}
Publicat 13/06/2011 la 19:33
sursa de către utilizator

voturi
19

Asta este O (log n), care este minimul. Cu toate acestea, puteți îmbunătăți eficiența (care pare a fi principalul lucru pe care aceste intervievatori pasă) și de a elimina posibilitatea de a stiva de preaplin (Tada!) Prin eliminarea recursivitate coada, transformând într - o buclă. De asemenea, codul nu funcționează în cazul în care arborele conține numere negative ... dacă te referi la non-negativ numere întregi, ar trebui să spun acest lucru, dar în cazul în care intervievatorul a spus doar „numere întregi“ , atunci ai nevoie de cod ușor diferit și un API diferit. (Ai putea păstra aceeași semnătură , dar funcția întoarce K în loc de -1 la eșec.)

BTW, din moment ce aceasta este o întrebare de interviu, de punere în aplicare prin apelarea unei funcții de bibliotecă ar spune cele mai multe interviuri că sunteți un desteptule sau lipsesc punctul sau nu știu cum să o rezolve. Nu mizerie în jurul valorii de acest fel de lucru, doar ajunge să lucreze la ceea ce știi intervievatorul vrea.

Aici este o punere în aplicare:

// 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;
}
Publicat 13/06/2011 la 20:25
sursa de către utilizator

voturi
5

Cred că ideea de aici este de a înregistra ultimul nod, după care trece la subarborelui drept. Prin urmare, codul va fi (a fost actualizat)

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)
}
Publicat 14/06/2011 la 03:06
sursa de către utilizator

voturi
1

Ceea ce primul răspuns a spus, iar aici este logica din spatele de ce nu se poate obține mai bine decât O (log n). Sunteți în căutarea pentru cel mai mare număr mai mic de K. Acest lucru este destul de aproape de asteptare BST-search / get.

Deși algoritmul original arata destul de bine, cred că acest lucru ar fi mai rapid:

    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

    }
Publicat 27/07/2011 la 11:11
sursa de către utilizator

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