بنقرة واحدة
algo-hash
Hash maps and sets — when O(1) lookup pays off, hash collisions, frozen keys, and hashing custom types.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Hash maps and sets — when O(1) lookup pays off, hash collisions, frozen keys, and hashing custom types.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Breadth-first search — shortest path on unweighted graphs, level-order traversal, and the `visited` discipline that prevents O(2^n) blowups.
Binary search invariants, half-open intervals, and the `lo<hi` template that beats off-by-one bugs.
Depth-first search — recursive vs iterative, recursion-depth gotchas, three-color cycle detection, topological sort.
Dynamic programming — state design, memoization vs tabulation, dimension-reduction, and when DP is the wrong tool.
Pick the right traversal — BFS for unweighted shortest path, Dijkstra for weighted, A* for goal-directed, 0/1-BFS for binary weights.
Greedy algorithms — exchange-argument proofs, when greedy beats DP, classic patterns (interval scheduling, Huffman, scheduling).
| name | algo-hash |
| description | Hash maps and sets — when O(1) lookup pays off, hash collisions, frozen keys, and hashing custom types. |
| when-to-use | Frequency counts, deduplication, two-sum and complement-lookup patterns, anagram grouping, prefix-sum + hash. |
Hashing trades memory for time. The trade is almost always worth it when you need membership / count / lookup by key. The dangerous failure mode is hashing a mutable type — Python silently breaks, JavaScript happily compares by reference instead of value.
O(1) insert / lookup / delete for keys with a
good hash distribution.dict, but never rely on it
for correctness — sort explicitly when order matters.tuple of hashables OK;
list, dict, set are not hashable.O(1) average, O(n) worst case
under adversarial collisions.O(n).O(n) for n distinct keys; load factor < 0.75 for
reasonable performance.def two_sum(nums: list[int], target: int) -> tuple[int, int] | None:
"""Indices (i, j) such that nums[i] + nums[j] == target, i < j."""
seen: dict[int, int] = {} # value -> first index
for j, x in enumerate(nums):
complement = target - x
if complement in seen:
return (seen[complement], j)
seen.setdefault(x, j)
return None
The complement-lookup pattern generalises: any "find pair s.t.
f(a, b) == target" reduces to "store seen f results, look up
the inverse." The same shape gives prefix-sum + hash for
"subarrays summing to k."
function groupAnagrams(words) {
const groups = new Map();
for (const w of words) {
// Sorted-letter signature is a canonical key for anagrams.
const key = [...w].sort().join("");
if (!groups.has(key)) groups.set(key, []);
groups.get(key).push(w);
}
return [...groups.values()];
}
Map is the right choice over a plain {} when keys are not
strings or when you need a defined iteration order. Set is the
right choice when you only care about membership.
list raises TypeError
on insertion. A custom class is hashable by default (id-based)
but compares by == only if you implement __eq__ and
__hash__ together — missing the pair gives baffling lookup
failures.{} vs set() in Python. {} is an empty dict, not a set;
set() is empty set. Easy to write seen = {} then call
seen.add(x) and crash.dict.get(k, []) returns a fresh list
each call. Use dict.setdefault or collections.defaultdict
when accumulating.{}. Coerced to string. Use
Map for non-string keys.NaN != NaN in both languages, so NaN-
keyed lookups can fail mysteriously.__eq__ / __hash__ contract.The "store seen, look up complement" pattern shows up in two-sum, 3-sum, contiguous-subarray-sum-equals-k, longest-substring-without- repeats, and dozens more. Recognise the shape and you skip the quadratic version.