upd
This commit is contained in:
@@ -1 +1,4 @@
|
|||||||
((org-mode . ((org-todo-keywords . ((sequence "TODO" | "DONE" "TOO_EASY"))))))
|
((org-mode . ((org-todo-keywords . ((sequence "TODO" | "DONE" "TOO_EASY")))
|
||||||
|
(eval . (let ((lc-el (expand-file-name "lc-org.el" (dir-locals-find-file default-directory))))
|
||||||
|
(when (and lc-el (file-exists-p lc-el) (not (featurep 'lc-org)))
|
||||||
|
(load-file lc-el)))))))
|
||||||
|
|||||||
@@ -14,7 +14,12 @@ An Anki-exportable study deck for NeetCode DSA problems.
|
|||||||
- Python and C++ solution stubs
|
- Python and C++ solution stubs
|
||||||
- A `NEETCODE` property linking back to the roadmap
|
- A `NEETCODE` property linking back to the roadmap
|
||||||
|
|
||||||
3. **Study flow** — open roadmap.org, pick a topic, pick a problem,
|
3. **Toolkit** (`toolkit/`) — your reference library:
|
||||||
|
- `tricks.org` — flashcards for patterns & tricks (exported to Anki)
|
||||||
|
- `notes.org` — deep implementation notes with explanations (exported to Anki)
|
||||||
|
- `suggestions.org` — pattern reference for quick lookup (not exported)
|
||||||
|
|
||||||
|
4. **Study flow** — open roadmap.org, pick a topic, pick a problem,
|
||||||
follow the Notes link, solve it, mark it DONE in both places.
|
follow the Notes link, solve it, mark it DONE in both places.
|
||||||
|
|
||||||
## File Layout
|
## File Layout
|
||||||
@@ -24,7 +29,10 @@ org/study_deck_02/
|
|||||||
├── AGENTS.md ← you are here
|
├── AGENTS.md ← you are here
|
||||||
├── roadmap.org ← generated by leetcode/extract.mjs
|
├── roadmap.org ← generated by leetcode/extract.mjs
|
||||||
├── toolkit/
|
├── toolkit/
|
||||||
│ └── tricks.org ← common patterns & templates
|
│ ├── tricks.org ← flashcards for patterns & tricks
|
||||||
|
│ ├── notes.org ← deep implementation notes
|
||||||
|
│ ├── suggestions.org ← pattern reference (not exported)
|
||||||
|
│ └── images/ ← diagrams, screenshots
|
||||||
└── dsa/
|
└── dsa/
|
||||||
├── arrays-hashing/
|
├── arrays-hashing/
|
||||||
│ ├── 0217-contains-duplicate.org
|
│ ├── 0217-contains-duplicate.org
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ Write your approach here.
|
|||||||
#+begin_src python
|
#+begin_src python
|
||||||
class Solution:
|
class Solution:
|
||||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||||
|
sb = {}
|
||||||
|
for xi, x in enumerate(nums):
|
||||||
|
want = target - x;
|
||||||
|
if want in sb:
|
||||||
|
return sb[want], xi
|
||||||
|
sb[x] = xi
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** TODO C++
|
** TODO C++
|
||||||
|
|||||||
@@ -40,9 +40,11 @@ Given an integer array ~nums~ and an integer ~k~, return /the/ ~k~ /most frequen
|
|||||||
Write your approach here.
|
Write your approach here.
|
||||||
|
|
||||||
** TODO Python
|
** TODO Python
|
||||||
#+begin_src python
|
#+begin_src python :lc-problem 347 :lc-lang python3
|
||||||
class Solution:
|
class Solution:
|
||||||
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
|
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
|
||||||
|
from collections import Counter
|
||||||
|
return [n for n, _ in Counter(nums).most_common(k)]
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** TODO C++
|
** TODO C++
|
||||||
|
|||||||
@@ -52,10 +52,40 @@ Write your approach here.
|
|||||||
|
|
||||||
** TODO Python
|
** TODO Python
|
||||||
#+begin_src python
|
#+begin_src python
|
||||||
|
from collections import defaultdict as dd
|
||||||
class Solution:
|
class Solution:
|
||||||
def stringMatching(self, words: List[str]) -> List[str]:
|
def stringMatching(self, words: List[str]) -> List[str]:
|
||||||
|
words = reversed(sorted(words))
|
||||||
|
def squash(word, trie):
|
||||||
|
lst = []
|
||||||
|
for c in word:
|
||||||
|
lst.append([trie, ''])
|
||||||
|
for i in range(len(lst)):
|
||||||
|
lst[i][0] = lst[i][0][c]
|
||||||
|
lst[i][1] += c
|
||||||
|
if not lst[i][0]['ads']:
|
||||||
|
lst[i][0]['ads'] = {lst[i][1]: [word]}
|
||||||
|
else:
|
||||||
|
lst[i][0]['ads'][lst[i][1]].append(word)
|
||||||
|
def in_trie(word, trie):
|
||||||
|
for c in word:
|
||||||
|
if c not in trie:
|
||||||
|
return []
|
||||||
|
trie = trie[c]
|
||||||
|
return [(word, bw) for bw in trie['ads'][word]]
|
||||||
|
trie_maker = lambda: dd(trie_maker)
|
||||||
|
trie = trie_maker()
|
||||||
|
ans = []
|
||||||
|
for s in words:
|
||||||
|
ans += in_trie(s, trie)
|
||||||
|
squash(s, trie)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
**
|
||||||
|
|
||||||
** TODO C++
|
** TODO C++
|
||||||
#+begin_src cpp
|
#+begin_src cpp
|
||||||
class Solution {
|
class Solution {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#+TITLE: NeetCode Roadmap
|
#+TITLE: NeetCode Roadmap
|
||||||
#+ANKI_DECK: study_deck_02
|
#+ANKI_DECK: study_deck_02
|
||||||
#+DATE: 2026-06-01
|
#+DATE: 2026-06-01
|
||||||
#+TODO: TODO DONE
|
#+TODO: TODO TOO_EASY DONE
|
||||||
#+STARTUP: overview
|
#+STARTUP: overview
|
||||||
|
|
||||||
Source: [[https://neetcode.io/roadmap][neetcode.io/roadmap]]
|
Source: [[https://neetcode.io/roadmap][neetcode.io/roadmap]]
|
||||||
@@ -32,7 +32,7 @@ Notes: [[file:dsa/arrays-hashing/0217-contains-duplicate.org]]
|
|||||||
*** DONE Python
|
*** DONE Python
|
||||||
*** DONE C++
|
*** DONE C++
|
||||||
Notes: [[file:dsa/arrays-hashing/0242-valid-anagram.org]]
|
Notes: [[file:dsa/arrays-hashing/0242-valid-anagram.org]]
|
||||||
** TODO 2678. Number of Senior Citizens :easy:
|
** TOO_EASY 2678. Number of Senior Citizens :easy:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:LEETCODE: [[https://leetcode.com/problems/number-of-senior-citizens/][Problem]]
|
:LEETCODE: [[https://leetcode.com/problems/number-of-senior-citizens/][Problem]]
|
||||||
:CPP: [[https://github.com/neetcode-gh/leetcode/blob/main/cpp/2678-number-of-senior-citizens.cpp][Solution]]
|
:CPP: [[https://github.com/neetcode-gh/leetcode/blob/main/cpp/2678-number-of-senior-citizens.cpp][Solution]]
|
||||||
@@ -51,7 +51,7 @@ Notes: [[file:dsa/arrays-hashing/2678-number-of-senior-citizens.org]]
|
|||||||
:VIDEO: [[https://youtube.com/watch?v=KLlXCFG5TnA][Watch]]
|
:VIDEO: [[https://youtube.com/watch?v=KLlXCFG5TnA][Watch]]
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
*** TODO Python
|
*** DONE Python
|
||||||
*** TODO C++
|
*** TODO C++
|
||||||
Notes: [[file:dsa/arrays-hashing/0001-two-sum.org]]
|
Notes: [[file:dsa/arrays-hashing/0001-two-sum.org]]
|
||||||
** TODO 1408. String Matching in an Array :easy:
|
** TODO 1408. String Matching in an Array :easy:
|
||||||
|
|||||||
@@ -25,3 +25,116 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** Why ~std::array~ over C-style arrays?
|
||||||
|
|
||||||
|
*** Type safety
|
||||||
|
- ~std::array<int, 26>~ carries its size in the type system
|
||||||
|
- C-style ~int freq[26]~ decays to ~int*~ when passed to functions — size info lost
|
||||||
|
- ~std::array~ knows its size: ~freq.size()~ always returns 26
|
||||||
|
|
||||||
|
*** Value semantics
|
||||||
|
- ~std::array~ can be copied, assigned, returned from functions like any value
|
||||||
|
- C arrays decay to pointers, can't be assigned:
|
||||||
|
#+begin_src cpp
|
||||||
|
int a[5] = {1,2,3,4,5};
|
||||||
|
int b[5];
|
||||||
|
b = a; // ERROR: array type 'int[5]' is not assignable
|
||||||
|
|
||||||
|
std::array<int,5> sa = {1,2,3,4,5};
|
||||||
|
std::array<int,5> sb;
|
||||||
|
sb = sa; // OK: copies all elements
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
*** No pointer decay
|
||||||
|
- C arrays silently decay to ~T*~ in many contexts — source of bugs
|
||||||
|
- ~std::array~ never decays; pass by reference explicitly: ~void f(const std::array<int,26>& a)~
|
||||||
|
|
||||||
|
*** Bounds checking (optional)
|
||||||
|
- ~.at(i)~ throws ~std::out_of_range~ on bad index
|
||||||
|
- ~[i]~ is unchecked (same as C array) — zero overhead if you want it
|
||||||
|
- C arrays have no checked access option
|
||||||
|
|
||||||
|
*** Works with STL algorithms
|
||||||
|
- ~std::all_of~, ~std::sort~, ~std::find~ etc. work directly on ~std::array~
|
||||||
|
- C arrays need explicit begin/end: ~std::all_of(std::begin(arr), std::end(arr), ...)~
|
||||||
|
- ~std::array~ has ~.begin()~, ~.end()~, ~.size()~
|
||||||
|
|
||||||
|
*** Cons of ~std::array~
|
||||||
|
- Slightly more verbose syntax: ~std::array<int, 26>~ vs ~int[26]~
|
||||||
|
- Template parameter required — can't use runtime size (use ~std::vector~ then)
|
||||||
|
- Compile-time dependency: size must be constexpr
|
||||||
|
|
||||||
|
** Why ~std::all_of~?
|
||||||
|
|
||||||
|
*** Declarative intent
|
||||||
|
- "All elements satisfy predicate" — reads like English
|
||||||
|
- vs manual loop: ~for (int i=0; i<26; i++) if (freq[i]!=0) return false;~ — imperative, more mental parsing
|
||||||
|
|
||||||
|
*** Zero overhead
|
||||||
|
- Compiles to same machine code as hand-written loop
|
||||||
|
- Optimizer inlines the lambda, unrolls if beneficial
|
||||||
|
- No performance penalty vs manual loop
|
||||||
|
|
||||||
|
*** Composability
|
||||||
|
- Can chain with other STL: ~std::any_of~, ~std::none_of~, ~std::count_if~
|
||||||
|
- Lambda can be arbitrarily complex without changing the loop structure
|
||||||
|
- Easy to swap predicate without restructuring code
|
||||||
|
|
||||||
|
*** Cons
|
||||||
|
- Slightly harder to debug (breakpoint inside lambda vs explicit loop)
|
||||||
|
- For trivial checks, manual loop may be more readable to some
|
||||||
|
- Requires ~<algorithm>~ include
|
||||||
|
|
||||||
|
** How does the compiler know 26 is okay?
|
||||||
|
|
||||||
|
*** Compile-time constant
|
||||||
|
- 26 is a literal — known at compile time
|
||||||
|
- Template parameter ~N~ in ~std::array<int, N>~ requires constexpr
|
||||||
|
- Compiler sees: "allocate space for 26 ints right here, right now"
|
||||||
|
|
||||||
|
*** Where does the memory live?
|
||||||
|
|
||||||
|
~std::array<int, 26>~ is an aggregate containing ~int data[26]~.
|
||||||
|
- If local variable → *stack* allocation
|
||||||
|
- If global/static → *data/bss* segment
|
||||||
|
- If member of class → wherever the object lives
|
||||||
|
|
||||||
|
Stack allocation is just moving the stack pointer:
|
||||||
|
#+begin_src asm
|
||||||
|
sub rsp, 104 ; 26 * 4 bytes = 104 bytes
|
||||||
|
; freq is now at [rsp], zero-initialized by {}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
*** Zero-initialization
|
||||||
|
- ~std::array<int, 26> freq{};~ — value-initialization, all zeros
|
||||||
|
- Compiler may emit ~memset~ or just zero the stack frame
|
||||||
|
- C-style ~int freq[26];~ is *uninitialized* — garbage values
|
||||||
|
- C-style ~int freq[26] = {};~ or ~int freq[26]{};~ also zero-initializes
|
||||||
|
|
||||||
|
*** Size is part of the type
|
||||||
|
- ~std::array<int, 26>~ and ~std::array<int, 27>~ are *different types*
|
||||||
|
- Can't accidentally mix them — type error at compile time
|
||||||
|
- C arrays: ~void f(int a[26])~ actually becomes ~void f(int* a)~ — size lost
|
||||||
|
|
||||||
|
*** Compile-time evaluation
|
||||||
|
- ~freq.size()~ is constexpr 26 — no runtime overhead
|
||||||
|
- Loop ~for (int i = 0; i < 26; i++)~ — compiler may unroll entirely
|
||||||
|
- With ~constexpr~ arrays, entire computation can happen at compile time
|
||||||
|
|
||||||
|
** What about ~std::unordered_map~?
|
||||||
|
|
||||||
|
When alphabet is *not* bounded (Unicode, arbitrary keys):
|
||||||
|
- ~std::map~ — O(log n) per op, ordered, tree-based
|
||||||
|
- ~std::unordered_map~ — O(1) average, hash table, unordered
|
||||||
|
|
||||||
|
For lowercase a-z, neither beats array:
|
||||||
|
- Array: ~freq[c - 'a']~ — direct index, one memory access
|
||||||
|
- Map/unordered_map: hash + probe/compare — multiple accesses, branches
|
||||||
|
|
||||||
|
** Questions for later
|
||||||
|
- How does the stack pointer move for arrays of different sizes?
|
||||||
|
- What's the alignment requirement for ~std::array<int, 26>~?
|
||||||
|
- Can ~std::array~ be ~constexpr~?
|
||||||
|
- What about ~std::array~ vs ~std::vector~ for dynamic sizes?
|
||||||
|
- How does the optimizer decide to unroll the ~all_of~ loop?
|
||||||
|
|||||||
Reference in New Issue
Block a user