Arrays and hashing are the first thing to drill because they show up in nearly every coding screen and they unlock the rest of the pattern catalog. If you can recognize when to trade memory for speed with a hash map, apply the two-pointer and sliding-window patterns, and narrate your complexity out loud, you will clear most first rounds. This guide gives you the patterns, a worked Two Sum example, complexity templates you can say verbatim, and a concrete week-by-week plan.
We run mock interviews all day, and the single most common failure we see is not exotic dynamic programming. It is candidates who brute-force an array problem, freeze when asked to optimize, and never reach for the hash map that turns O(n^2) into O(n). Fix that reflex and your pass rate jumps.
Why arrays and hashing come first
Array manipulation and hash-based lookups are the foundation topics in every popular interview prep track. Structured lists like NeetCode 150 open with an "Arrays & Hashing" category on purpose: the early problems teach the pattern-recognition habits everything else builds on. Practitioners who work through those sets note that the first block of problems is where you learn hash maps for lookups, two pointers for array manipulation, and prefix sums, which then recur across trees, graphs, and DP.
The time pressure is real. Amazon-style loops typically give you roughly 45 minutes per coding round, and prep guides recommend budgeting around 35 to 40 minutes on the harder problem and reserving the last 10 to 15 minutes for testing. In that window there is no time to relearn how a hash set works. You want array and hashing mechanics to be automatic so you can spend your thinking budget on the actual problem. Company-specific breakdowns like our Amazon and Google pages show how heavily first rounds lean on these fundamentals.
The core patterns
Most array and hashing questions are a remix of a handful of patterns. Learn to name them and half the battle is spotting which one applies.
- Hash map for O(1) lookup. You are searching for a complement, a duplicate, a count, or a previously seen value. When you catch yourself writing a nested loop to "check if something exists," that is the signal to add a hash map. In many array problems, replacing the inner loop with a map lookup is the key optimization.
- Hash map for frequency counting. Tally occurrences, then reason over the counts. "Count the Number of Consistent Strings" (junior) is a clean example: put the
allowedcharacters in a set and check each word against it in one pass. - Grouping by a canonical key. Map each item to a signature and bucket items that share it. "Groups of Strings" (staff) uses a bitmask of the 26 letters as the key so strings that connect land in the same group.
- Two pointers. For sorted arrays or in-place partitioning, move two indices toward or away from each other instead of scanning repeatedly.
- Sliding window. For contiguous subarrays or substrings under a constraint, expand and shrink a window while maintaining a running aggregate, often backed by a hash map of counts.
- Prefix / running aggregate. Precompute cumulative sums or bitwise ORs so range queries become O(1). "Bitwise ORs of Subarrays" (mid_senior) is a hashing-plus-aggregate hybrid: you track the set of distinct OR values ending at each index.
Two harder problems in our bank show where hashing meets bit tricks: "Find Xor-Beauty of Array" (mid_senior) reduces to a counting argument, and "Number of Ways to Wear Different Hats to Each Other" (staff) uses bitmask state that you memoize in a map. If a problem's constraints mention 40 items or fewer, bitmasking over a hash of states is often the intended path.
A worked example: Two Sum in one pass
Two Sum is the canonical hash-map problem, and interviewers still use it as a warm-up. The naive solution checks every pair in O(n^2). The one-pass hash map does it in O(n) time and O(n) space by remembering values you have already seen.
function twoSum(nums, target):
seen = {} # value -> index
for i in range(len(nums)):
need = target - nums[i]
if need in seen:
return [seen[need], i]
seen[nums[i]] = i
return [] # no pair found
Trace it on nums = [2, 7, 11, 15], target = 9:
| i | nums[i] | need = target - nums[i] | need in seen? | action |
|---|---|---|---|---|
| 0 | 2 | 7 | no | store seen[2] = 0 |
| 1 | 7 | 2 | yes (index 0) | return [0, 1] |
The insight to narrate: you never look forward, only backward at values already stored, so a single pass is enough. Time is O(n) because each element is processed once, and space is O(n) for the map. Say exactly that in the interview. Getting the complexity claim right, out loud, is often worth as much as the code.
Complexity you should state out loud
Interviewers grade how you talk about cost, not just the final Big-O. Keep two templates ready.
For arrays:
| Operation | Cost |
|---|---|
| Array (random access): lookup by index | O(1) |
| Append | O(1) amortized; insert/delete at arbitrary index O(n) |
| Search by value | O(n) |
For hash tables, use this sentence almost verbatim: "Average-case O(1) for insert and lookup; worst-case O(n) due to collisions or resizing, especially with a poorly chosen hash function." That single caveat signals maturity. It is also technically accurate: modern implementations mitigate the worst case, and Java 8 and later convert a bucket to a red-black tree once it passes a threshold, so a degenerate bucket degrades to O(log n) rather than O(n). The treeification threshold is 8 entries with a minimum table capacity of 64.
One more composition worth knowing: an LRU cache is a hash map plus a doubly linked list, giving O(1) get and put. The map finds the node, the list tracks recency. If asked to design one, state that pairing first, then fill in the pointer bookkeeping.
A four-week practice plan
Grinding random problems does not build the reflexes. Structure does. Here is a schedule that assumes about one hour on weekdays and longer timed sessions on weekends.
Week 1: fundamentals, no timer. Learn each pattern in isolation.
- Mon/Tue: hash-set and frequency problems. Do "Count the Number of Consistent Strings," then Two Sum and Contains Duplicate.
- Wed/Thu: two pointers and sliding window (Valid Palindrome, Longest Substring Without Repeating Characters).
- Fri: prefix sums and running aggregates.
- Weekend: re-solve the week's problems from scratch, writing tests first.
Week 2: grouping and mediums. Add canonical-key thinking.
- Mon/Tue: "Groups of Strings" and Group Anagrams.
- Wed/Thu: "Bitwise ORs of Subarrays" and "Reschedule Meetings for Maximum Free Time I."
- Fri: review; write a one-line pattern label at the top of each solution.
- Weekend: one 45-minute timed session with two mediums.
Week 3: speed and narration. Start talking through every solve.
- Two 45-minute timed mock interviews (Tue and Thu), out loud, explaining approach and complexity before coding.
- Other days: revisit missed problems and harder ones like "Minimum Number of Work Sessions to Finish the Tasks."
Week 4: interview simulation. Full loops.
- Three timed 45-minute mocks across the week under realistic conditions.
- Attempt "Find Xor-Beauty of Array" and "Number of Ways to Wear Different Hats to Each Other" to stretch into bitmask hashing.
- Cool down by re-explaining your five weakest solutions.
The non-negotiable habit: state your approach and its Big-O before you type, and dry-run your code on a small input before you claim it works.
FAQ
How many array and hashing problems should I solve before interviewing?
Depth beats volume. Solving about 30 to 40 problems that cover every pattern here, then re-solving your weak ones, beats blindly grinding 200. The goal is instant pattern recognition, not a high solve count.
When should I reach for a hash map instead of sorting?
Use a hash map when you need existence or frequency lookups and order does not matter; it gives average O(1) access. Sort first when the problem needs ordering, deduplication with adjacency, or a two-pointer sweep. Sorting costs O(n log n) but sometimes removes the need for extra space.
What is the difference between a hash set and a hash map in interviews?
A hash set stores unique keys for membership tests; a hash map stores key-to-value pairs. Reach for a set when you only ask "have I seen this?" and a map when you need to remember something about each key, like its index or count.
Do interviewers care about hash collisions?
Usually only conceptually. You should be able to say lookups are average-case O(1) and worst-case O(n) from collisions or resizing, and that good implementations mitigate this (Java, for example, treeifies dense buckets to O(log n)). You rarely need to implement a hash function yourself.