diff --git a/org/study_deck_02/AGENTS.md b/org/study_deck_02/AGENTS.md index 806e695..cfe3b37 100644 --- a/org/study_deck_02/AGENTS.md +++ b/org/study_deck_02/AGENTS.md @@ -23,6 +23,8 @@ An Anki-exportable study deck for NeetCode DSA problems. org/study_deck_02/ ├── AGENTS.md ← you are here ├── roadmap.org ← generated by leetcode/extract.mjs +├── toolkit/ +│ └── tricks.org ← common patterns & templates └── dsa/ ├── arrays-hashing/ │ ├── 0217-contains-duplicate.org @@ -121,3 +123,14 @@ This deck starts with NeetCode 150. To add more: header. They'll all export to the same Anki deck. - **Flashcards** — add `** Front` / `** Back` sections to any note for Anki-style cards (see root `AGENTS.md` for format). + +## Backlinking Convention + +Every `.org` file should link back to `roadmap.org` via a property: + +- Problem notes use `:NEETCODE:` linking to the roadmap heading +- Toolkit/tricks use `:ROADMAP:` linking to a relevant problem +- Roadmap entries use `:TRICK:` linking to relevant tricks + +This keeps the web of links navigable in both directions — from +roadmap to notes, from notes to tricks, and tricks back to problems. diff --git a/org/study_deck_02/dsa/arrays-hashing/0242-valid-anagram.org b/org/study_deck_02/dsa/arrays-hashing/0242-valid-anagram.org index a3c9ec9..e025399 100644 --- a/org/study_deck_02/dsa/arrays-hashing/0242-valid-anagram.org +++ b/org/study_deck_02/dsa/arrays-hashing/0242-valid-anagram.org @@ -1,5 +1,5 @@ #+PROPERTY: STUDY_DECK_02 -* TODO 0242. Valid Anagram :easy: +* DONE 0242. Valid Anagram :easy: :PROPERTIES: :NEETCODE: [[file:../../roadmap.org::*0242. Valid Anagram][0242. Valid Anagram]] :END: @@ -26,21 +26,36 @@ Given two strings ~s~ and ~t~, return ~true~ if ~t~ is an anagram of ~s~, and ~f *Follow up:* What if the inputs contain Unicode characters? How would you adapt your solution to such a case? -** TODO Approach +** DONE Approach Write your approach here. -** TODO Python +** DONE Python #+begin_src python class Solution: def isAnagram(self, s: str, t: str) -> bool: #+end_src -** TODO C++ +** DONE C++ #+begin_src cpp +#include +#include class Solution { public: - bool isAnagram(string s, string t) { - + bool isAnagram(std::string s, std::string t) { + std::map ctr; + for (char c: s) { + ctr[c] += c; } + for (char c: t) { + if (ctr[c] == 0) { + return false; + } + ctr[c] -= 1; + if (ctr[c] == 0) { + ctr.erase(c); + } + } + return ctr.size() == 0; + } }; #+end_src diff --git a/org/study_deck_02/roadmap.org b/org/study_deck_02/roadmap.org index f6c3e2a..f8da80b 100644 --- a/org/study_deck_02/roadmap.org +++ b/org/study_deck_02/roadmap.org @@ -6,7 +6,7 @@ Source: [[https://neetcode.io/roadmap][neetcode.io/roadmap]] -* TODO Arrays & Hashing [1/12] +* TODO Arrays & Hashing [2/12] ** DONE 0217. Contains Duplicate :easy: :PROPERTIES: @@ -19,16 +19,18 @@ Source: [[https://neetcode.io/roadmap][neetcode.io/roadmap]] *** DONE Python *** DONE C++ Notes: [[file:dsa/arrays-hashing/0217-contains-duplicate.org]] -** TODO 0242. Valid Anagram :easy: +** DONE 0242. Valid Anagram :easy: :PROPERTIES: :LEETCODE: [[https://leetcode.com/problems/valid-anagram/][Problem]] :CPP: [[https://github.com/neetcode-gh/leetcode/blob/main/cpp/0242-valid-anagram.cpp][Solution]] :PYTHON: [[https://github.com/neetcode-gh/leetcode/blob/main/python/0242-valid-anagram.py][Solution]] :VIDEO: [[https://youtube.com/watch?v=9UtInBqnCgA][Watch]] +:RELATED: [[https://leetcode.com/problems/group-anagrams/][049. Group Anagrams]], [[https://leetcode.com/problems/ransom-note/][383. Ransom Note]], [[https://leetcode.com/problems/first-unique-character-in-a-string/][387. First Unique Character]] +:TRICK: [[file:toolkit/tricks.org::*Task: Count character frequencies faster than map][Count char freq faster than map]] :END: -*** TODO Python -*** TODO C++ +*** DONE Python +*** DONE C++ Notes: [[file:dsa/arrays-hashing/0242-valid-anagram.org]] ** TODO 2678. Number of Senior Citizens :easy: :PROPERTIES: diff --git a/org/study_deck_02/toolkit/suggestions.org b/org/study_deck_02/toolkit/suggestions.org new file mode 100644 index 0000000..47385b0 --- /dev/null +++ b/org/study_deck_02/toolkit/suggestions.org @@ -0,0 +1,107 @@ +#+PROPERTY: STUDY_DECK_02 +#+TITLE: DSA Tricks & Patterns + +* Common Patterns +** Sliding Window +Use when: contiguous subarray/substring, "longest/shortest/most k" +Template: +#+begin_src cpp +int left = 0; +for (int right = 0; right < n; right++) { + // expand window + while (/* window invalid */) { + // shrink window + left++; + } + // update answer +} +#+end_src + +** Two Pointers +Use when: sorted array, palindrome, pair sum +Template: +#+begin_src cpp +int l = 0, r = n - 1; +while (l < r) { + if (/* condition */) l++; + else r--; +} +#+end_src + +** Binary Search +Use when: monotonic function, "minimum maximum", "first/last" +Template: +#+begin_src cpp +int lo = 0, hi = n; +while (lo < hi) { + int mid = lo + (hi - lo) / 2; + if (/* check(mid) */) hi = mid; + else lo = mid + 1; +} +#+end_src + +** BFS vs DFS +- BFS: shortest path (unweighted), level-order, queue +- DFS: path existence, backtracking, cycle detection, stack/recursion + +** Union-Find +Use when: connected components, cycle detection, grouping +- Path compression + union by rank = O(α(n)) + +** Monotonic Stack +Use when: next greater/smaller element, stock span +Template: +#+begin_src cpp +stack st; +for (int i = 0; i < n; i++) { + while (!st.empty() && st.top() < arr[i]) { + // process st.top() + st.pop(); + } + st.push(i); +} +#+end_src + +** Topological Sort +Use when: dependency ordering, DAG, course schedule +- Kahn's (BFS + in-degree) or DFS post-order reversal + +** Dijkstra's +Use when: shortest path, non-negative weights, weighted graph +- Priority queue + relaxation + +** Bit Manipulation Tricks +- ~x = -x - 1 +- x & (x - 1) clears lowest set bit +- x & -x isolates lowest set bit +- XOR swap: a ^= b; b ^= a; a ^= b; + +** KMP / Z-Algorithm +Use when: pattern matching, repeated substrings +- KMP: O(n + m), failure function +- Z: O(n + m), Z-array + +** DP State Design +- Ask: what do I need to track? (index, remaining, previous choice) +- State = f(index, constraint1, constraint2, ...) +- Space optimize with rolling array when only previous row needed + +** Graph Coloring (2-coloring / Bipartite) +Use when: odd cycle check, two groups +- BFS/DFS alternating colors + +** Prefix Sum +Use when: subarray sum, range queries +- Build once O(n), query O(1) + +** Trie +Use when: prefix search, autocomplete, word dictionary +- Each node = character, path = word + +** Heap / Priority Queue +Use when: k-th element, merge k sorted, median maintenance +- C++: `priority_queue` (max-heap by default) + +** Fast & Slow Pointers +Use when: cycle detection, linked list midpoint +- Floyd's tortoise and hare diff --git a/org/study_deck_02/toolkit/tricks.org b/org/study_deck_02/toolkit/tricks.org new file mode 100644 index 0000000..f6c4b44 --- /dev/null +++ b/org/study_deck_02/toolkit/tricks.org @@ -0,0 +1,21 @@ +#+ANKI_DECK: study_deck_02 +#+TITLE: DSA Tricks & Patterns + +* Task: Count character frequencies faster than map :dsa:counting:array:string:retrieval::production: +:PROPERTIES: +:ANKI_NOTE_TYPE: Basic +:ROADMAP: [[file:../roadmap.org::*0242. Valid Anagram][0242. Valid Anagram]] +:END: + +** Front +Write C++ to count character frequencies in a string using a +fixed-size array instead of ~std::map~ (assume lowercase a-z only). + +** Back +#+begin_src cpp +std::array freq{}; +for (char c : s) freq[c - 'a']++; +#+end_src + +*Why:* O(1) per access vs O(log n) for ~std::map~. Use when alphabet +is bounded and small.