DEV Community

Real Dev
Real Dev

Posted on Originally published at realdev9868.hashnode.dev

A 30-Day DSA Plan for Placements, Built Around Patterns (Not Problem Counts)

A common way to prepare for placement coding rounds is to open a list of hundreds of problems and start at number one. A month later, a new problem still feels like a blank page.

A better approach: learn a small set of patterns well enough that you recognise them in problems you've never seen. This post gives you a 30-day plan built that way, with a working Python template for each core pattern.

Thirty days won't make you an expert. But it can take you from "I don't know where to start" to "I can usually tell what kind of problem this is."

Before Day 1: are you ready for DSA?

DSA assumes you can already write loops, conditionals and functions comfortably. If a palindrome check or "second largest element" still feels slow, spend a week or two on basic logic first. Our logic building track covers conditions, loops, recursion, arrays and strings in that order, and it's a reasonable warm-up.

Pick one language for the whole month. The examples below use Python because it keeps templates short.

How to spend each day

Aim for about 2 hours:

  • 20 min: learn or revise the pattern (read, or trace it by hand on paper).
  • 80 min: solve 2–3 problems that use it. Give yourself about 25 minutes per problem before you look at a hint.
  • 20 min: write a short note for each problem: what the pattern was, and what clue in the question should have pointed you to it.

That last step matters most: you're learning the clues, not collecting solutions.

Week 1 (Days 1–7): Arrays, strings and hashing

Days 1–2: Array basics, reversing, rotating, and stating the time complexity of everything you write.
Days 3–4: Strings: counting characters, anagrams, palindromes.
Days 5–6: Hash maps and sets: the "have I seen this before?" pattern.
Day 7: Revise and solve 3 mixed problems without notes.

Pattern: hash map lookup. The clue is "find a pair or duplicate," where the brute-force answer is two nested loops.

def two_sum(nums, target):
    seen = {}                      # value -> index
    for i, x in enumerate(nums):
        if target - x in seen:
            return [seen[target - x], i]
        seen[x] = i
    return []

assert two_sum([2, 7, 11, 15], 9) == [0, 1]
Enter fullscreen mode Exit fullscreen mode

One pass, O(n) time, O(n) extra space. Say that trade-off out loud in an interview.

Week 2 (Days 8–14): Two pointers, sliding window, prefix sums, binary search

Days 8–9: Two pointers on sorted arrays.
Days 10–11: Sliding window (fixed and variable size).
Day 12: Prefix sums.
Day 13: Binary search, including "binary search on the answer."
Day 14: Revision plus one timed set: 3 problems in 75 minutes.

Pattern: two pointers. The clue is a sorted array, or "pairs, triplets, or in-place partitioning."

def pair_with_sum_sorted(nums, target):
    lo, hi = 0, len(nums) - 1
    while lo < hi:
        s = nums[lo] + nums[hi]
        if s == target:
            return (lo, hi)
        if s < target:
            lo += 1
        else:
            hi -= 1
    return None

assert pair_with_sum_sorted([1, 3, 4, 6, 9], 10) == (0, 4)
Enter fullscreen mode Exit fullscreen mode

Pattern: variable sliding window. The clue is "longest/shortest contiguous subarray or substring such that…"

def longest_unique_substring(s):
    last = {}          # char -> last index seen
    start = best = 0
    for i, ch in enumerate(s):
        if ch in last and last[ch] >= start:
            start = last[ch] + 1     # shrink window past the repeat
        last[ch] = i
        best = max(best, i - start + 1)
    return best

assert longest_unique_substring("abcabcbb") == 3
Enter fullscreen mode Exit fullscreen mode

Pattern: prefix sum + hash map. The clue is "count subarrays whose sum equals k." Unlike a sliding window, it also works with negative numbers.

def count_subarrays_with_sum(nums, k):
    count, running = 0, 0
    freq = {0: 1}                  # prefix sum -> how many times seen
    for x in nums:
        running += x
        count += freq.get(running - k, 0)
        freq[running] = freq.get(running, 0) + 1
    return count

assert count_subarrays_with_sum([1, 1, 1], 2) == 2
Enter fullscreen mode Exit fullscreen mode

Pattern: binary search. Write one version you trust and reuse it every time:

def lower_bound(nums, target):
    """First index i with nums[i] >= target."""
    lo, hi = 0, len(nums)
    while lo < hi:
        mid = (lo + hi) // 2
        if nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid
    return lo

assert lower_bound([1, 2, 4, 4, 7], 4) == 2
Enter fullscreen mode Exit fullscreen mode

Week 3 (Days 15–21): Linked lists, stacks, queues, recursion, trees

Days 15–16: Linked lists: reversal, fast/slow pointers (finding the middle, detecting a cycle).
Day 17: Stacks: valid parentheses, monotonic stack ("next greater element").
Day 18: Recursion and backtracking basics (subsets, permutations).
Days 19–20: Binary trees: DFS (pre/in/post-order) and level-order BFS.
Day 21: Revision.

If pointers feel abstract, watch them move: our DSA visualizers let you step through arrays, linked lists, stacks/queues and sorting in the browser. Use them alongside problems, not instead of them.

Pattern: monotonic stack. The clue is "next greater/smaller element" or "how many days until…"

def next_greater(nums):
    res = [-1] * len(nums)
    stack = []                     # indices with no answer yet
    for i, x in enumerate(nums):
        while stack and nums[stack[-1]] < x:
            res[stack.pop()] = x
        stack.append(i)
    return res

assert next_greater([2, 1, 3, 2, 5]) == [3, 3, 5, 5, -1]
Enter fullscreen mode Exit fullscreen mode

Week 4 (Days 22–30): Graphs, heaps, intro to DP, mocks

Days 22–23: Graphs: adjacency lists, BFS, DFS, counting connected components.
Day 24: Heaps: top-k elements, merging sorted lists (heapq in Python, priority_queue in C++).
Days 25–27: Dynamic programming basics: climbing stairs, house robber, coin change, longest common subsequence.
Days 28–29: Two full mock rounds: 2 problems, 60 minutes, talk out loud as you go.
Day 30: Go back through your notes and redo every problem you marked "needed a hint."

Pattern: BFS for shortest path in an unweighted graph or grid. The clue is "minimum number of steps/moves."

from collections import deque

def shortest_path_grid(grid):
    """Steps from top-left to bottom-right; 0 = open, 1 = wall."""
    n, m = len(grid), len(grid[0])
    if grid[0][0] or grid[n-1][m-1]:
        return -1
    q = deque([(0, 0, 0)])
    seen = {(0, 0)}
    while q:
        r, c, d = q.popleft()
        if (r, c) == (n - 1, m - 1):
            return d
        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < n and 0 <= nc < m and not grid[nr][nc] and (nr, nc) not in seen:
                seen.add((nr, nc))
                q.append((nr, nc, d + 1))
    return -1

assert shortest_path_grid([[0, 0, 0],
                           [1, 1, 0],
                           [0, 0, 0]]) == 4
Enter fullscreen mode Exit fullscreen mode

Pattern: 1-D dynamic programming. The clue is "number of ways" or "min/max cost," where each answer builds on smaller answers.

def coin_change(coins, amount):
    INF = float("inf")
    dp = [0] + [INF] * amount      # dp[a] = fewest coins to make a
    for a in range(1, amount + 1):
        for c in coins:
            if c <= a:
                dp[a] = min(dp[a], dp[a - c] + 1)
    return dp[amount] if dp[amount] != INF else -1

assert coin_change([1, 2, 5], 11) == 3
Enter fullscreen mode Exit fullscreen mode

For DP, write the recurrence in words first, then code it.

A quick "which pattern?" cheat sheet

If the problem says… Try…
sorted array, pair/triplet Two pointers
longest/shortest contiguous… Sliding window
count subarrays with sum k Prefix sum + hash map
"seen before", duplicates, pairs Hash map / set
minimum/maximum value that satisfies a condition Binary search on the answer
next greater/smaller Monotonic stack
minimum steps, levels BFS
all combinations/subsets Backtracking
number of ways, min cost Dynamic programming
top k, k-th largest Heap

Mistakes to avoid

  • Watching solutions instead of struggling. Twenty-five honest minutes teach you more than a ten-minute video.
  • Skipping complexity analysis. State it before the interviewer asks.
  • Never practising under time pressure. Do one timed set a week from Week 2.

Save the templates above in one file, run it (every assert should pass silently), and add to it as you learn new patterns. By Day 30 it's your revision sheet.

All the best for placements!

— Schoolabe team

Top comments (0)