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
ndə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 siqnal | Struktur | Niyə |
|---|---|---|
| "Açara görə tap", "bu dəyər varmı?", "neçə dəfə rast gəlir?" | Hash map / hash set | Orta 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 map —
O(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ış
ndə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əllO(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)və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.