Two Sum (Hash Map)
# O(n) time, O(n) space
def two_sum(nums: list[int], target: int) -> list[int]:
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
print(two_sum([2, 7, 11, 15], 9)) # [0, 1]Valid Palindrome (Two Pointers)
def is_palindrome(s: str) -> bool:
left, right = 0, len(s) - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if s[left].lower() != s[right].lower():
return False
left += 1; right -= 1
return True
print(is_palindrome("A man, a plan, a canal: Panama")) # TrueFibonacci (Dynamic Programming)
# Bottom-up DP: O(n) time, O(1) space
def fib(n):
if n <= 1: return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
# Memoization with lru_cache
from functools import lru_cache
@lru_cache(maxsize=None)
def fib_memo(n):
if n <= 1: return n
return fib_memo(n-1) + fib_memo(n-2)
print(fib(10)) # 55Binary Search
def binary_search(nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
print(binary_search([1, 3, 5, 7, 9], 7)) # 3Valid Anagram
from collections import Counter
def is_anagram(s: str, t: str) -> bool:
return Counter(s) == Counter(t)
print(is_anagram("anagram", "nagaram")) # True
print(is_anagram("rat", "car")) # FalseποΈ Practical Exercise
Reinforce the patterns above:
- Re-solve Two Sum without looking, then state its time and space complexity.
- Implement Valid Palindrome ignoring case and non-alphanumeric characters.
- Write both a recursive and an iterative Fibonacci and compare them.
- Implement binary search and test it on a sorted list, including the not-found case.
π₯ Challenge Exercise
Pick three of these problems and, for each, write a clean solution, add edge-case tests (empty input, duplicates, not found), and analyze the Big-O time and space complexity. Then try to improve at least one brute-force solution to a more optimal one (e.g. nested loop β hash map). Bonus: explain your approach out loud as you would in an interview.
π Summary
- These classic problems cover hash maps, two pointers, dynamic programming, and binary search.
- Two Sum uses a hash map to reach O(n) time instead of O(nΒ²).
- Two-pointer techniques solve palindrome and array problems efficiently.
- Memoization/DP turns exponential recursion into linear time.
- Binary search requires sorted input and runs in O(log n).
- In interviews, explain your reasoning, handle edge cases, and state complexity.
Interview Questions on Coding Challenges
- How does the hash-map approach make Two Sum O(n)?
- What is the two-pointer technique and when is it useful?
- Why is naive recursive Fibonacci exponential, and how does DP fix it?
- What are the requirements for binary search to work?
- How do you check if two strings are anagrams efficiently?
- How do you analyze the time and space complexity of a solution?
- How do you talk through a problem in a coding interview?
Related Topics
FAQ
Clarify the problem and constraints, work through a small example, state a brute-force idea, then refine it. Code cleanly while explaining your reasoning, test with edge cases, and finish by analyzing time and space complexity.
Instead of checking every pair (O(nΒ²)), you store each numberβs complement in a hash map and look it up in O(1). One pass yields O(n) time at the cost of O(n) extra space.
It recomputes the same subproblems exponentially many times. Caching results with memoization (or building up iteratively) reduces it to O(n) time.
A sorted sequence. It repeatedly halves the search range, achieving O(log n) time. On unsorted data you must sort first or use a linear scan.
