DSA Python Interview Prep Problem Solving

DSA Problem Walkthroughs — How I Actually Think Through Coding Problems

Not just solutions — the reasoning process behind them, from brute force to optimal

Sanskruti Varade · Interview Prep · ~7 min read

Most DSA tutorials show you the answer. They present a clean, optimal solution, walk through the code line by line, and call it done. That's useful — but it skips the most important part: how do you arrive at that solution when you're staring at a blank screen in an interview?

This post is about the thinking process, not just the output. I'll walk through three problems — one from each of the most common interview categories — and show exactly how I reason from first principles to an optimal solution.

Problem 1: Two Sum (Arrays + Hashing)

Given an array of integers and a target, return the indices of two numbers that add up to the target.

Step 1 — Brute force first

Always start here. Two nested loops, check every pair:

def two_sum_brute(nums, target):
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            if nums[i] + nums[j] == target:
                return [i, j]

Time complexity: O(n²). Works, but won't pass large inputs.

Step 2 — Identify the bottleneck

The inner loop is doing repeated lookups. What data structure gives us O(1) lookup? A hash map.

Step 3 — Reframe the problem

Instead of "find two numbers that sum to target," think: "for each number, check if its complement (target - num) already exists in what I've seen so far."

def two_sum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i

Time complexity: O(n). One pass, one hash map. The insight: whenever you're doing repeated searches inside a loop, ask if a hash map can eliminate the inner scan.

Problem 2: Longest Substring Without Repeating Characters (Sliding Window)

Given a string, find the length of the longest substring without repeating characters.

Step 1 — Recognize the pattern

We're dealing with a contiguous sequence and a constraint (no repeats). This is the sliding window pattern.

Step 2 — Build the window

def length_of_longest_substring(s):
    char_index = {}
    left = 0
    max_len = 0

    for right, char in enumerate(s):
        if char in char_index and char_index[char] >= left:
            left = char_index[char] + 1
        char_index[char] = right
        max_len = max(max_len, right - left + 1)

    return max_len

Time complexity: O(n). The key line is char_index[char] >= left — it ensures we only shrink the window based on characters inside the current window, not stale entries.

The insight: sliding window works on any problem asking for an optimal contiguous subarray or substring under a constraint.

Problem 3: Climbing Stairs (Dynamic Programming)

You can climb 1 or 2 steps at a time. How many distinct ways can you reach the nth step?

Step 1 — Think recursively first

To reach step n, you either came from step n-1 or step n-2. So ways(n) = ways(n-1) + ways(n-2) — that's just Fibonacci.

Step 2 — Optimize space

You only ever need the last two values:

def climb_stairs(n):
    if n <= 2:
        return n
    a, b = 1, 2
    for _ in range(3, n + 1):
        a, b = b, a + b
    return b

O(n) time, O(1) space. The insight: DP problems follow the same arc — recursive intuition → memoization → bottom-up iteration → space optimization.

The Meta-Framework I Use for Every Problem

  1. Understand before coding — Restate the problem. Identify input/output. Ask about edge cases.
  2. Brute force out loud — Never jump to optimal. Shows structured thinking and gives a correctness baseline.
  3. Identify the bottleneck — Repeated scanning → hash map. Redundant subproblems → DP. Sorted data → binary search. Contiguous constraint → sliding window.
  4. Code the optimized solution — Only after reasoning through the approach verbally.
  5. Test with examples — Happy path first, then edge cases.

Patterns Worth Drilling

One problem per pattern per day is more effective than grinding 10 random problems.

A Note on Language Choice

I solve in Python for interviews. The syntax is concise, collections are built-in, and you spend less time on boilerplate. collections.defaultdict, heapq, and collections.deque cover 80% of what you need beyond basic arrays and hash maps.

← Back to Blog