Knowledge / Computer Science and Engineering / DSA interview patterns

DSA interview patterns

Computer Science and Engineering (B.E./B.Tech) · Algorithms · free study notes for exams, placements and interviews

In short

A "pattern" is a reusable shape of solution — two pointers, sliding window, prefix sums, monotonic stack, heap for top-K, binary search on the answer, and so on — that solves a whole family of problems once you recognise the signal in the question. Interviewers deliberately ask variants rather than famous problems, so pattern recognition beats memorising solutions: roughly 15-20 patterns cover the large majority of problems set in coding rounds. This is examined in company online assessments and DSA interviews (Amazon, Microsoft, Google India, Flipkart, Zomato, Swiggy, Razorpay, Atlassian, Walmart Global Tech, Adobe), in mass placement tests (TCS NQT, Infosys, Wipro NLTH, Accenture, Cognizant) and on HackerRank, HackerEarth, CodeChef and Codeforces. University "Design and Analysis of Algorithms" labs and GATE CS set the same structures under their classical names. The skill measured is not coding speed but the ability to map constraints to a complexity target, pick the pattern, state its invariant and prove the bound.

Explained

Reading the problem: constraints decide the pattern

Linear-scan patterns: two pointers, sliding window, fast-and-slow, prefix sum

Stack, queue and monotonic structures

Hashing, heaps and top-K

Arrays in place, intervals, and search on the answer

Trees, recursion-shaped and design patterns

Interview craft around the pattern

Key points

Formulas and examples

Time budget: operations ≈ 10⁸ per second on a typical judge (varies by language and machine); choose a complexity so that f(n) ≤ time limit × 10⁸.
Range sum from prefix sums: sum(i..j) = P[j+1] − P[i], where P[0] = 0 and P[k] = a[0]+…+a[k−1].
Count of subarrays with sum = k: for each prefix p, add count of previously seen prefix (p − k); initialise map with {0 : 1}.
Variable sliding window cost: each index moves l and r at most once each → ≤ 2n pointer moves → O(n) amortised.
Floyd cycle: fast travels exactly 2 × slow; with tail length μ and cycle length λ, a pointer from the head and one from the meeting point, both at speed 1, meet at the cycle start after μ steps.
Binary search on answer: while (lo < hi) { mid = lo + (hi − lo)/2; if (feasible(mid)) hi = mid; else lo = mid + 1; } → answer = lo. Iterations ≈ log₂(hi − lo).
Monotonic stack cost: ≤ n pushes and ≤ n pops → O(n) total, even with a nested-looking while loop.
Total number of subarrays of an array of size n = n(n+1)/2; subsets = 2ⁿ; permutations = n!.
Top-K with size-k heap: O(n log k) time, O(k) space, versus O(n log n) for a full sort.
n (input size)Feasible complexityPattern usually intended
≤ 10O(n!)permutations, brute-force backtracking
≤ 20-25O(2ⁿ)subsets, bitmask enumeration
≤ 500O(n³)triple loop, interval/matrix methods
≤ 5,000O(n²)pair loops, 2-D tables
≤ 10⁵-10⁶O(n log n)sort, heap, binary search on answer
≤ 10⁷O(n)two pointers, sliding window, prefix sum
value range ≤ 10⁹O(log n)binary search, maths

Example 1 - fixed-size sliding window. Maximum sum of any 3 consecutive elements of [2, 1, 5, 1, 3, 2].

Example 2 - two pointers on a sorted array. Find a pair summing to 14 in [1, 3, 4, 6, 8, 11].

Example 3 - prefix sum with a hash map. Count subarrays with sum = 7 in [3, 4, 7, 2, −3, 1, 4, 2].

Example 4 - binary search on the answer. Minimum ship capacity to carry weights [4, 8, 5, 6, 3] within D = 3 days.

Example 5 - monotonic stack. Next greater element for [2, 1, 2, 4, 3] (−1 if none), scanning right to left with a decreasing stack.

# variable-size sliding window: longest substring with no repeated character
def longest_unique(s):
    last, best, l = {}, 0, 0
    for r, ch in enumerate(s):
        if ch in last and last[ch] >= l:
            l = last[ch] + 1          # shrink past the previous occurrence
        last[ch] = r
        best = max(best, r - l + 1)   # invariant: s[l..r] has no repeats
    return best

# monotonic stack skeleton: previous smaller element
def prev_smaller(a):
    st, out = [], []
    for x in a:
        while st and st[-1] >= x:
            st.pop()
        out.append(st[-1] if st else -1)
        st.append(x)
    return out
Problem signalPatternTypical complexity
Sorted array, find a pair/tripleTwo pointersO(n) after sort
Contiguous subarray, all positiveSliding windowO(n)
Contiguous subarray, negatives presentPrefix sum + hash mapO(n)
Many range sum queries, no updatesPrefix sum arrayO(1) per query
Many range updates, one final readDifference arrayO(1) per update
Next/previous greater or smallerMonotonic stackO(n)
k-th largest / k closestSize-k heapO(n log k)
Running median of a streamTwo heapsO(log n) per item
Values are a permutation of 1..nCyclic sort / index markingO(n), O(1) space
Minimise a maximum, or vice versaBinary search on answerO(n log range)
Same group / connectivity queriesUnion-Find~O(1) amortised
Prefix of stringsTrieO(word length)

Where it is used

Interview questions

Common mistakes

Related topics

Time and space complexity · Searching and binary search · Recursion and backtracking · Dynamic programming · Graph algorithms: BFS, DFS and shortest paths · Sorting algorithms

Open in the Knowledge reader →Find jobs →