Senior 3 min · March 06, 2026

Pair-Sum O(N²) Timeout — Hash Map Fix for Array Interview

50k elements crashed a take-home with O(N²) nested loops.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • Two Pointers: Iterate from both ends on a sorted array — O(N) time, O(1) space
  • Sliding Window: Maintain a window over a contiguous section — O(N) time, O(1) or O(k) space
  • Prefix Sums: Precompute cumulative sums for O(1) range queries — O(N) preprocess, O(1) query
  • Hash Map: Store complements or frequencies for O(N) time with O(N) space
  • Binary Search: Halve the search space on sorted data — O(log N) time, O(1) space
Plain-English First

Think of an array like a row of numbered lockers at school. Each locker has a fixed position and holds exactly one item. Most array interview problems are really just puzzles about how to walk between those lockers as efficiently as possible — without opening every single one. The trick interviewers test isn't whether you know what a locker is. It's whether you know which lockers to skip.

Arrays are the most interviewed data structure in software engineering — full stop. Google, Amazon, Meta, and every startup in between use array problems as their first filter because they reveal how you think about memory, iteration, and trade-offs. A candidate who brute-forces every array problem signals they haven't yet developed algorithmic intuition. A candidate who spots patterns signals they're ready to write production code under constraints.

The real issue isn't that array problems are hard. It's that most resources teach you the answer without teaching you the pattern. You memorize a solution, walk into the next interview, see a slightly different problem, and blank. What you actually need is a small toolkit of reusable strategies — two pointers, sliding window, prefix sums, hash maps for frequency counting — that cover 90% of what you'll face.

By the end of this article you'll recognize which pattern to reach for within the first 30 seconds of reading a problem. You'll have complete, runnable code for all 10 canonical array problems, understand the time and space complexity of each, and know exactly what follow-up questions interviewers use to separate good candidates from great ones.

The Two-Pointer Pattern: Two Sum Implementation

One of the most frequent array patterns is the 'Two-Pointer' approach. Instead of a nested loop O(N²) brute force, we use two indices moving toward each other on a sorted array. This reduces the time complexity to O(N log N) (due to sorting) or O(N) if the array is already sorted. This is a foundational technique used in problems like 'Container With Most Water' and '3Sum'.

io/thecodeforge/arrays/TwoSumProvider.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package io.thecodeforge.arrays;

import java.util.Arrays;

/**
 * TheCodeForge: Two-Pointer Implementation for Sorted Arrays.
 * Time Complexity: O(N) if sorted / O(N log N) if unsorted.
 */
public class TwoSumProvider {
    public int[] findTwoSum(int[] numbers, int target) {
        // In a real interview, always clarify if you should sort it yourself
        Arrays.sort(numbers);
        int left = 0;
        int right = numbers.length - 1;

        while (left < right) {
            int currentSum = numbers[left] + numbers[right];
            if (currentSum == target) {
                return new int[]{left + 1, right + 1}; // Standard 1-based index return
            } else if (currentSum < target) {
                left++;
            } else {
                right--;
            }
        }
        return new int[]{-1, -1};
    }
}
Output
// Example: Input [2, 7, 11, 15], Target 9 -> Output [1, 2]
Forge Tip: Pruning the Search Space
Type this code yourself rather than copy-pasting. The muscle memory of writing it will help it stick. Pay attention to how the search space is pruned: by moving the right pointer, we effectively discard all sums larger than the current one for that specific left index.
Production Insight
Two-pointer works only on sorted data.
If you sort an unsorted array, you lose original indices — a problem if the problem asks for original positions.
Rule: always ask if the array is sorted before writing a two-pointer solution.
Key Takeaway
Two-pointer is the optimal choice for sorted arrays with O(1) space.
Hash Map wins for unsorted arrays when you need original indices.
Always confirm the sorting constraint before diving into code.
Choosing Two-Pointer vs Hash Map for Two Sum
IfArray is sorted and space is O(1) requirement
UseUse two-pointer — O(N) time, O(1) space
IfArray is unsorted but you can sort (no index requirement)
UseSort (O(N log N)) then two-pointer — O(N log N) time, O(1) space
IfArray is unsorted and original indices matter
UseUse Hash Map — O(N) time, O(N) space

The Sliding Window Pattern: Maximum Subarray Sum (Kadane's Algorithm)

The Sliding Window is essential for problems involving contiguous subarrays. Kadane's Algorithm is the definitive solution for finding the maximum subarray sum. It avoids the O(N²) trap of checking every possible subarray by making a local vs. global decision at each element: 'Do I add this element to the existing sum, or start a new window here?'

io/thecodeforge/arrays/MaxSubarray.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package io.thecodeforge.arrays;

/**
 * io.thecodeforge implementation of Kadane's Algorithm.
 * Crucial for LeetCode Medium/Hard variations like 'Maximum Product Subarray'.
 */
public class MaxSubarray {
    public int maxSubArray(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        
        int maxSoFar = nums[0];
        int currentMax = nums[0];

        for (int i = 1; i < nums.length; i++) {
            // The Forge Logic: Max(current element alone, current element + previous window)
            currentMax = Math.max(nums[i], currentMax + nums[i]);
            maxSoFar = Math.max(maxSoFar, currentMax);
        }
        return maxSoFar;
    }
}
Output
// Example: Input [-2,1,-3,4,-1,2,1,-5,4] -> Output 6 ([4,-1,2,1])
Efficiency Note: Linear vs Quadratic
Sliding window is often the difference between an algorithm that times out on large inputs and one that passes in a fraction of a second. In production, this saves cloud compute costs significantly when processing logs or streams.
Production Insight
Kadane's algorithm fails if you reset currentMax to zero when it goes negative — that only works for arrays that don't contain all negatives.
For all-negative arrays, you need to start with the first element, not zero.
Rule: initialize currentMax and maxSoFar with the first element, not with 0.
Key Takeaway
Kadane's algorithm is the gold standard for maximum subarray sum.
Always test with all-negative arrays to confirm your initialisation is correct.
Range: O(N) time, O(1) space — optimal for contiguous subarray statistics.
When to Use Kadane vs Sliding Window for Subarray Problems
IfNeed maximum subarray sum (any length)
UseUse Kadane's O(N)
IfNeed maximum subarray sum with fixed-length window
UseUse sliding window (prefix sum or two-pointer) O(N)
IfNeed maximum product subarray
UseUse modified Kadane keeping min and max — O(N)

Two Sum Using Hash Map (Unordered Array)

When the array is unsorted and you cannot sort it (or need to preserve original indices), the Hash Map approach shines. Iterate through the array once, storing each element's value as the key and its index as the value. For each element, check if the complement (target - current) exists in the map. If it does, you've found the pair. This runs in O(N) time and O(N) space.

io/thecodeforge/arrays/TwoSumHashMap.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package io.thecodeforge.arrays;

import java.util.HashMap;
import java.util.Map;

/**
 * TheCodeForge: Two Sum using Hash Map (unsorted array).
 * Time: O(N), Space: O(N)
 */
public class TwoSumHashMap {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                return new int[]{map.get(complement), i};
            }
            map.put(nums[i], i);
        }
        return new int[]{-1, -1};
    }
}
Output
// Input: [2,7,11,15], target 9 -> Output [0,1] (0-based indices when unsorted)
Forge Tip: HashMap Order Matters
We store the current element after checking the complement. This avoids using the same element twice and handles duplicates correctly.
Production Insight
Hash Map approach is safe when the array can contain large values or negative numbers — it's not sensitive to sorting order.
But it uses O(N) memory. In memory-constrained environments (e.g., embedded systems), two-pointer might be better even if it requires sorting.
Rule: trade space for time only when you have the budget.
Key Takeaway
Hash Map turns O(N²) into O(N) for pair-sum problems.
It works on unsorted data and preserves original indices.
Benchmark: for 100k elements, Hash Map runs in ~5ms; nested loops take minutes.
When to Use Hash Map for Two Sum
IfArray is unsorted, indices needed, O(N) space allowed
UseUse Hash Map — O(N) time, O(N) space
IfArray is unsorted but O(1) space required
UseSort (O(N log N)) then two-pointer — O(N log N) time, O(1) space
IfArray is sorted
UseUse two-pointer — O(N) time, O(1) space

Sliding Window with Hash Map: Longest Substring Without Repeating Characters

Although it's a string problem, the technique applies to any contiguous sequence — including arrays of characters. We use a sliding window with a hash map to track the last index of each character. Expand the window to the right, and if a character repeats, shrink the window from the left. This runs in O(N) time and O(min(N, alphabet size)) space.

io/thecodeforge/strings/LongestSubstringWithoutRepeating.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package io.thecodeforge.strings;

import java.util.HashMap;
import java.util.Map;

/**
 * TheCodeForge: Sliding window with HashMap for longest substring without repeating characters.
 * Works on any array of comparable elements.
 */
public class LongestSubstringWithoutRepeating {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> lastIndex = new HashMap<>();
        int maxLen = 0, left = 0;
        for (int right = 0; right < s.length(); right++) {
            char c = s.charAt(right);
            if (lastIndex.containsKey(c)) {
                // Move left to one past the previous occurrence (if greater)
                left = Math.max(lastIndex.get(c) + 1, left);
            }
            lastIndex.put(c, right);
            maxLen = Math.max(maxLen, right - left + 1);
        }
        return maxLen;
    }
}
Output
// Input: "abcabcbb" -> Output 3 ("abc" or "bca")
Edge Case: Very Large Input
For arrays with a limited unique value set (e.g., only ASCII), you can replace HashMap with a fixed array of size 128 for better cache performance.
Production Insight
The sliding window + HashMap pattern is used extensively in log parsing and stream processing.
If you need to handle streaming data (e.g., network packets), this is the approach that works in O(N) with bounded memory.
Rule: the HashMap stores the latest occurrence; moving left correctly is the hardest part.
Key Takeaway
Sliding window + HashMap solves longest substring with no repeats in O(N).
The HashMap holds last occurrence index — shrinking left is the critical operation.
Convert to fixed array for character sets to reduce overhead.
Choosing Sliding Window Variants
IfWindow length is fixed (e.g., sum of k elements)
UseSimple sliding window — maintain sum, add right, subtract left
IfWindow length is variable based on condition (e.g., no repeats)
UseSliding window + HashMap (or fixed array) — expand right, shrink left as needed
IfNeed maximum subarray sum with variable window
UseKadane's algorithm — not typical sliding window

Binary Search Strategy on Rotated Sorted Array

When an array is sorted but rotated, standard binary search needs modification. The key insight: one half of the array is always fully sorted. Determine which half the target belongs to and adjust low and high accordingly. This is a classic LeetCode Medium that separates good candidates from excellent ones.

io/thecodeforge/arrays/SearchRotatedSortedArray.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package io.thecodeforge.arrays;

/**
 * TheCodeForge: Search in Rotated Sorted Array.
 * Time: O(log N), Space: O(1)
 */
public class SearchRotatedSortedArray {
    public int search(int[] nums, int target) {
        int low = 0, high = nums.length - 1;
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (nums[mid] == target) return mid;
            // Determine which half is sorted
            if (nums[low] <= nums[mid]) { // left half is sorted
                if (target >= nums[low] && target < nums[mid]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            } else { // right half is sorted
                if (target > nums[mid] && target <= nums[high]) {
                    low = mid + 1;
                } else {
                    high = mid - 1;
                }
            }
        }
        return -1;
    }
}
Output
// Input: [4,5,6,7,0,1,2], target 0 -> Output 4
Integer Overflow with mid Calculation
Always use mid = low + (high - low) / 2 instead of (low + high) / 2 to avoid integer overflow with large arrays. This is a common bug in production code.
Production Insight
Rotated array binary search is not just an interview trick — it maps to real problems like finding a version in a rolling deployment where versions are sequential but a rollback changed the order.
The pattern of checking which half is sorted is reusable in any scenario where partial order exists.
Rule: use the sorted half to decide the search direction.
Key Takeaway
Rotated array search is O(log N) except when duplicates force O(N).
The core pattern: find the sorted half, then decide if target lies in it.
Always verify the array has no duplicates — if it does, the problem changes.
Binary Search Variants
IfArray is sorted normally
UseStandard binary search — O(log N)
IfArray is sorted then rotated
UseModified binary search — check sorted half
IfArray is sorted but contains duplicates
UseModified binary search with left&right trimming — O(N) worst-case
● Production incidentPOST-MORTEMseverity: high

The O(N²) That Killed a Take-Home Assessment

Symptom
Test case with 50k elements ran for over 10 seconds and hit the platform's timeout limit.
Assumption
The candidate assumed the input was small enough that O(N²) would pass.
Root cause
Brute-force nested loop (N² = 2.5 billion comparisons) on a 50k array.
Fix
Replace with a Hash Map single pass: O(N) time, O(N) space — completed in under 50ms.
Key lesson
  • Always assume the largest input size will be tested.
  • For pair-sum problems, the Hash Map approach is safer than two pointers (which requires sorting first).
  • When you see a timeout, the first thing to check is whether you're using O(N²) when O(N) exists.
Production debug guideCommon symptoms and root causes when your code fails hidden test cases3 entries
Symptom · 01
Solution passes sample tests but fails on edge cases
Fix
Check empty arrays, single-element arrays, all-negative numbers, and duplicate values. Write explicit assertions for these.
Symptom · 02
Array index out of bounds error
Fix
Examine loop boundaries: off-by-one is the most frequent bug. Use <= versus < carefully. For two-pointer, ensure left < right conditions.
Symptom · 03
Timeout on large inputs
Fix
Identify the time complexity. If you see O(N²) when O(N) is possible (e.g., using nested loop for max subarray instead of Kadane), refactor immediately.
★ Array Interview Problem Debugging Cheat SheetQuick fixes for the most common pitfalls in array coding interviews.
Two-pointer returns wrong result for unsorted array
Immediate action
Ask the interviewer whether the array is sorted. If not, decide whether sorting is allowed (adds O(N log N)) or use a Hash Map.
Commands
Arrays.sort(nums); // only if you have permission to modify
Set left = 0, right = arr.length - 1; while(left < right) { ... }
Fix now
If sorting is not allowed, switch to HashMap approach: store (value, index) as you iterate.
Sliding window produces wrong sum for negative numbers+
Immediate action
Check if you're resetting the window properly when the sum drops below zero. Kadane's algorithm handles negatives correctly.
Commands
current = Math.max(nums[i], current + nums[i]);
maxSoFar = Math.max(maxSoFar, current);
Fix now
For maximum subarray, use Kadane's algorithm — not a general sliding window.
Binary search infinite loop+
Immediate action
Verify the loop condition: while (low <= high) for basic search, while (low < high) for lower bound.
Commands
int mid = low + (high - low) / 2; // avoid overflow
Check if mid is calculated inside the loop correctly.
Fix now
Reduce the range: ensure low and high are updated without skipping the target.
Array Problem Pattern Cheat Sheet
PatternBest Use CaseTypical Complexity
Two PointersSearching pairs in sorted arrays, reversing, or mergingO(N)
Sliding WindowFinding contiguous subarrays, strings, or window averagesO(N)
Prefix SumsRange sum queries or subarray sum calculationsO(1) after O(N) preprocessing
Hash Map/SetFrequency counting or O(1) existence checksO(N) Time / O(N) Space
Binary SearchSearching in sorted data or finding optimal thresholdsO(log N)

Key takeaways

1
Array problems are categorized by patterns (Two Pointers, Sliding Window, etc.), not just individual solutions. Recognize the pattern before coding.
2
Optimization usually involves trading Space (Hash Maps) for Time, or using sorting to unlock Pointers.
3
Always check for array bounds and off-by-one errors during implementation. They are the most common bugs.
4
Practice daily
the forge only works when it's hot 🔥

Common mistakes to avoid

5 patterns
×

Brute Force Instinct

Symptom
Using nested loops O(N²) when a linear pattern like Sliding Window or Two Pointers exists. This is an immediate red flag in FAANG interviews.
Fix
Before writing any code, pause for 30 seconds. Identify if the problem involves contiguous subarrays, pairs, or frequencies. Match to a pattern. Practice pattern recognition daily.
×

Boundary Blindness

Symptom
Forgetting to handle edge cases like empty arrays, single-element arrays, or all-negative numbers (common in Kadane's). The solution fails on such inputs.
Fix
Write explicit test cases for: empty, single element, all same, all negative, large numbers. Use defensive coding: check for null and length == 0.
×

Over-optimization

Symptom
Failing to ask if the input array is sorted. If it isn't, sorting it (O(N log N)) might be slower than using a Hash Map (O(N)).
Fix
Always ask the interviewer clarifying questions: 'Is the array sorted? Can we modify it? Do we care about original indices?' Let those answers drive the algorithm choice.
×

Integer Overflow in Mid Calculation

Symptom
Binary search using (low + high) / 2 overflows for large arrays (near Integer.MAX_VALUE). Causes infinite loop or crash.
Fix
Use low + (high - low) / 2. This avoids overflow and is the industry standard.
×

Resetting Kadane's currentMax to 0

Symptom
When the array contains all negative numbers, resetting currentMax to 0 yields a wrong answer (returns 0 instead of the max negative).
Fix
Initialize currentMax and maxSoFar to nums[0], and update with currentMax = Math.max(nums[i], currentMax + nums[i]).
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
Given an array of integers, move all 0's to the end while maintaining th...
Q02SENIOR
Find the longest contiguous subarray that contains at most k distinct el...
Q03SENIOR
Search in a Rotated Sorted Array: Find a target value in an array that w...
Q04JUNIOR
Given an array of stock prices, find the maximum profit from a single bu...
Q05SENIOR
Find the first missing positive integer in an unsorted array. (LeetCode ...
Q01 of 05JUNIOR

Given an array of integers, move all 0's to the end while maintaining the relative order of the non-zero elements. (LeetCode Easy - Two Pointers)

ANSWER
Use a two-pointer approach: one pointer (nonZeroIndex) tracks the position to place the next non-zero element, the other iterates through the array. When a non-zero is found, swap it with the element at nonZeroIndex and increment nonZeroIndex. This is O(N) time and O(1) space.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
How do I decide between using a Hash Map or Two Pointers for Two Sum?
02
What is the most efficient way to find the 'Missing Number' in an array?
03
Why is Kadane's algorithm better than a brute-force subarray search?
04
How do I handle duplicate values in a rotated array binary search?
05
What's the difference between a fixed-length sliding window and a variable-length one?
🔥

That's Coding Patterns. Mark it forged?

3 min read · try the examples if you haven't

1 / 17 · Coding Patterns
Next
Top 10 String Interview Problems