Sparround

Hansı məsələdə hansı struktur?

İnterview-da data strukturu seçimi "hansını daha yaxşı bilirəm" sualı deyil. Bir sual verirsən və cavab özü çıxır:

"Bu məsələdə hansı əməliyyat ən çox təkrarlanır?"

Səbəb sadədir: hər struktur bəzi əməliyyatları O(1), bəzilərini O(n) edir. Ən çox təkrarlanan əməliyyat ucuz olmalıdır, qalanları isə nə olursa olsun. 1000 dəfə açar üzrə axtarış və 1 dəfə sıralama edirsənsə, hash map seç — sıralamanın O(n log n) olması heç nəyi dəyişmir.

Üç addımlı çərçivə:

  • 1. Əməliyyatları sadala — məsələdə hansı əməliyyatlar var: əlavə etmək, silmək, açarla tapmaq, minimumu götürmək, aralıq soruşmaq, sıra ilə gəzmək?
  • 2. Tezliyi qiymətləndir — hansı biri döngənin içindədir, yəni n dəfə təkrarlanır?
  • 3. Həmin əməliyyatı ucuzlaşdıran strukturu seç — və qalanların bahalaşmasını ucadan qəbul et

Üçüncü addımın sonuncu hissəsi ən çox unudulan hissədir: hər seçim bir güzəştdir və güzəşti özün adlandırmaq güclü siqnaldır.

Məsələdəki siqnalStrukturNiyə
"Açara görə tap", "bu dəyər varmı?", "neçə dəfə rast gəlir?"Hash map / hash setOrta halda `O(1)` axtarış və əlavə; sıra saxlanmır
"Təkrarları at", "unikal olanları say"SetÜzvlük yoxlaması `O(1)`, dəyər saxlamağa ehtiyac yoxdur
"Sonuncu əlavə olunan", "geri qayıt", "mötərizələr uyğundurmu"Stack (LIFO)Yalnız son element lazımdır — `O(1)` push/pop
"Növbə ilə emal et", "təbəqə-təbəqə gəz"Queue (FIFO)BFS və bütün ardıcıl emal məsələlərinin əsası
"Ən böyük K", "minimumu təkrar-təkrar götür", "median axını"Heap (priority queue)`O(log n)` əlavə, `O(1)` ən kiçiyə baxmaq; tam sıralamaya ehtiyac yoxdur
"X ilə Y arasındakı dəyərlər", "ən yaxın dəyər", "sıra ilə gəz"Sıralanmış massiv / balanslı ağac (TreeMap, SplayTreeSet)Sıra qorunur — aralıq sorğuları `O(log n)`; hash map bunu edə bilmir
"Prefiks ilə başlayanlar", "avtotamamlama"Trie (prefix tree)Axtarış prefiksin uzunluğundan asılıdır, söz sayından yox
"Ortadan tez-tez əlavə/sil", "indeks lazım deyil"Linked list (və ya deque)Node əlində olanda `O(1)` silmə; amma indekslə müraciət `O(n)`
"Bu iki element eyni qrupdadırmı", "qrupları birləşdir"Union-Find (disjoint set)Birləşdirmə və yoxlama praktiki olaraq `O(1)`

Cədvəl seçimi asanlaşdırır, amma interview-da güzəşti adlandırmaq daha çox dəyər verir. Hər strukturun bir zəif tərəfi var və onu özün deməlisən:

  • Hash mapO(1) axtarış verir, amma sıra saxlamır və əlavə yaddaş tələb edir. "Ən kiçik açar hansıdır?" sualına cavab vermək üçün bütün açarları gəzmək lazımdır: O(n)
  • Heap — minimumu ucuz verir, amma sıralanmış siyahı deyil. Heap-i gəzsən, elementlər sıralı gəlmir; "3-cü ən kiçik" sualı üçün heap birbaşa uyğun deyil
  • Sıralanmış massiv — aralıq sorğuları və binary search əladır, amma ortaya əlavə etmək `O(n)`-dir, çünki elementlər sürüşdürülməlidir
  • Balanslı ağac — həm sıra, həm O(log n) əlavə verir, amma hash map-dən yavaşdır və koda mürəkkəblik gətirir
  • Trie — prefiks axtarışı üçün əvəzsizdir, amma yaddaş tələbkardır; kiçik lüğətdə sadə siyahı üzərində filtr daha praktikdir
  • Linked list — ortadan O(1) silmə, amma cache-ə dost deyil; praktikada kiçik massivlər linked list-dən sürətli olur

Bu cümlələri hazır saxla: "Hash map götürürəm, çünki axtarış dominantdır — əvəzində sıra itir, amma bu məsələdə sıra lazım deyil." Güzəşti özün deyəndə intervyuer onu sənə "tutulmuş səhv" kimi qaytara bilmir.

Bunu interview-da necə səsləndirmək lazımdır. Struktur seçimi 20-30 saniyəlik bir bənd olmalıdır — nə susmaq, nə də beş dəqiqəlik mühazirə.

Dörd cümləlik şablon:

  • (1) Dominant əməliyyatı adlandır: "Burada döngənin içində hər element üçün 'bu dəyəri əvvəl görmüşəmmi' soruşulur — yəni axtarış n dəfə təkrarlanır."
  • (2) Strukturu seç və mürəkkəbliyi de: "Ona görə hash set götürürəm: axtarış orta halda O(1), ümumi həll O(n)."
  • (3) Güzəşti qeyd et: "Əvəzində O(n) əlavə yaddaş sərf edirəm və elementlərin sırası itir."
  • (4) Alternativi rədd et — səbəbi ilə: "Sıralayıb two pointers da işlədə bilərdim, O(n log n)O(1) yaddaş; giriş çox böyükdürsə və yaddaş kritikdirsə həmin variantı seçərdim."

Dördüncü cümlə cavabı orta səviyyədən yuxarı qaldıran hissədir: sən yalnız bir həll bilmirsən, iki həll arasında kontekstə görə seçim edirsən.

Ən çox rast gəlinən səhv: strukturu seçib səbəbini deməmək. İntervyuer "niyə hash map?" soruşanda "çünki sürətlidir" cavabı zəifdir — "çünki bu məsələdə açar üzrə axtarış dominant əməliyyatdır və hash map onu O(1) edir" cavabı isə güclüdür. Fərq bircə cümlədədir, amma qiymətləndirmədə böyükdür.

Interview məsləhəti: brute force həllini danışarkən özünə bu sualı ver — "burada hansı əməliyyat O(n)-dir və onu O(1) edən struktur varmı?" Optimallaşdırmaların böyük əksəriyyəti məhz bu bir sualdan çıxır: iç-içə döngə (O(n²)) çox vaxt hash map ilə O(n)-ə düşür, hər dəfə minimum axtarmaq heap ilə O(log n)-ə, hər dəfə "bu aralıqda nə var" sualı isə sıralanmış strukturla O(log n)-ə. Optimallaşdırma sehr deyil — bahalı əməliyyatı tapıb ona uyğun struktur seçməkdir.