Solving Problems & Interview Patterns
Why this lesson
DSA pays off in two ways: writing efficient app code, and passing the coding interviews that gate most mobile jobs. Both come down to the same skill — recognising a pattern and applying the right structure. This lesson gives you a method and the patterns that cover most problems.
A step-by-step method
- Understand & clarify — what’s the input/output? Edge cases (empty, duplicates, huge)?
- Start brute force — the simplest correct solution, even if O(n²). Get something working.
- Find the bottleneck — what makes it slow? Usually a repeated scan or nested loop.
- Apply a structure/pattern — can a hash map make a lookup O(1)? Can sorting + two pointers help?
- Analyse complexity — state the time and space Big-O.
- Test edge cases — empty input, one item, duplicates, very large input.
The patterns that solve most problems
- Hash map for lookups — turn O(n) scans into O(1). (e.g. “two-sum”: store seen numbers in a map.)
- Two pointers — on sorted arrays, move from both ends (e.g. pair sums, palindromes).
- Sliding window — for “longest/shortest substring/subarray with a condition”.
- BFS/DFS — for trees and graphs (paths, connectivity, levels).
- Sorting first — many problems become easy once data is ordered.
- Memoization / DP — when sub-problems repeat.
A worked example: two-sum
“Find two numbers that add to a target.” Brute force checks every pair — O(n²). The hash-map pattern makes it O(n):
fun twoSum(nums: IntArray, target: Int): Pair<Int, Int>? {
val seen = HashMap<Int, Int>() // value -> index
for ((i, n) in nums.withIndex()) {
val need = target - n
seen[need]?.let { return it to i } // found the complement -> O(1)
seen[n] = i
}
return null
}
Notice the move: a nested-loop scan became a single pass with O(1) lookups — the exact technique you use to speed up real app code.
Interview tips for mobile roles
- Think out loud — interviewers assess your reasoning, not just the answer.
- State complexity — always give time and space Big-O.
- Connect to mobile — mention real uses (LRU cache, list diffing, nav stack) when relevant; it shows applied understanding.
- Don’t freeze — start brute force, then optimise. A working O(n²) beats a broken O(n).
How to practise
Solve a few problems regularly (arrays/strings, hash maps, two pointers, trees, then graphs/DP). Re-implement the LRU cache from memory. Most importantly, when you hit a slow spot in your own app, stop and ask “which structure/pattern fixes this?” — that turns DSA from theory into instinct.
Common mistakes
- Jumping to code before understanding the problem and edge cases.
- Optimising prematurely instead of getting a correct solution first.
- Not stating complexity or testing edge cases.
Summary: Approach any DSA problem methodically: clarify, brute-force, find the bottleneck, apply a pattern (hash map, two pointers, sliding window, BFS/DFS, sorting, memoization), analyse complexity, and test edges. The same patterns that ace interviews are exactly what make your app code fast.