Strategies for Getting Unstuck
Here are battle-tested strategies for every type of being stuck.
Strategy 1: Start with Brute Force
When to use: You have no idea where to start.
How:
- Ignore efficiency completely
- Think: "How would a computer solve this the dumb way?"
- Code that solution
- Optimize later
Example - Two Sum:
# Start here (even though it's O(n²))
def two_sum(nums, target):
# Check every pair - simple and clear
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
if nums[i] + nums[j] == target:
return [i, j]
return []
# Then optimize to O(n)
def two_sum_optimized(nums, target):
seen = {}
for i, num in enumerate(nums):
if target - num in seen:
return [seen[target - num], i]
seen[num] = i
return []
Why this works:
- Gets you started (momentum is everything)
- Shows you understand the problem
- Gives you something to optimize
- Demonstrates problem-solving process
Strategy 2: Solve a Simpler Version
When to use: Problem feels overwhelming.
How:
- Remove constraints
- Reduce input size
- Add restrictions
- Solve the easier version
- Gradually add complexity back
Example - Edit Distance:
# Original: Find minimum edits to transform word1 to word2
# Simpler version 1: What if we can only insert?
def min_inserts(s1, s2):
return len(s2) - len(s1)
# Simpler version 2: What if strings are length 1?
def edit_distance_base(s1, s2):
if s1 == s2:
return 0
return 1
# Simpler version 3: What if one string is empty?
def edit_distance_base_case(s1, s2):
if not s1:
return len(s2)
if not s2:
return len(s1)
# Now build up to full solution...
Progressive simplification:
- String → Array → Single element
- All operations → One operation
- General case → Specific case
- Dynamic → Static
Strategy 3: Work Through Examples Manually
When to use: You have an idea but can't implement it.
How:
- Choose a small example
- Solve it by hand step-by-step
- Write down every decision you make
- Notice the pattern
- Code that pattern
Example - Valid Parentheses:
Input: "([{}])"
Manual steps:
1. See '(' - need to match with ')' later - save it
2. See '[' - need to match with ']' later - save it
3. See '{' - need to match with '}' later - save it
4. See '}' - must match most recent unmatched ('{') ✓
5. See ']' - must match most recent unmatched ('[') ✓
6. See ')' - must match most recent unmatched ('(') ✓
Pattern noticed: Last opened, first closed → Stack!
Then code:
def is_valid(s):
stack = []
pairs = {'(': ')', '[': ']', '{': '}'}
for char in s:
if char in pairs: # Opening
stack.append(char)
else: # Closing
if not stack or pairs[stack.pop()] != char:
return False
return len(stack) == 0
Strategy 4: Change Your Perspective
When to use: Current approach isn't working.
How:
Perspective 1: Think about Data Structure
Current: "I need to search for elements"
New: "What data structure gives fast search? → Hash map/set"
Perspective 2: Think about What You're Tracking
Current: "I need to find the maximum"
New: "I'm tracking the max seen so far → One variable"
Perspective 3: Think about Constraints
Current: "I need to check all possibilities"
New: "Wait, sorted input → Binary search possible"
Perspective 4: Think About the End State
Current: "How do I start?"
New: "Work backwards - what would the answer look like?"
Example - House Robber:
# Perspective 1: "What do I need to decide at each house?"
# → Include/exclude decision → Recursion/DP
# Perspective 2: "What info do I need from previous houses?"
# → Max money from previous two houses
# Perspective 3: "Can I derive current from previous?"
# → Yes: dp[i] = max(dp[i-1], dp[i-2] + nums[i])
def rob(nums):
if len(nums) <= 2:
return max(nums) if nums else 0
prev2, prev1 = nums[0], max(nums[0], nums[1])
for i in range(2, len(nums)):
current = max(prev1, prev2 + nums[i])
prev2, prev1 = prev1, current
return prev1
Strategy 5: Ask for a Hint (The Right Way)
When to use: After 10-15 minutes of genuine effort.
Don't say:
- ❌ "I have no idea"
- ❌ "Just tell me the answer"
- ❌ "Is it dynamic programming?"
Do say:
- ✅ "I've tried X and Y. Could you give me a hint about the approach?"
- ✅ "I'm thinking about using a hash map, but I'm stuck on how to handle duplicates. Any hints?"
- ✅ "I have an O(n²) solution. Is there a way to optimize this?"
Good hint requests show:
- What you've tried
- Where you're stuck specifically
- That you've made genuine effort
Strategy 6: Rubber Duck Debugging
When to use: Code almost works but something's wrong.
How:
- Explain your code line-by-line out loud
- Trace through with an example
- Say what you expect at each step
- Notice where reality differs from expectation
Example:
You: "So first I create a hash map... then I iterate through nums.
For index 0, value 2, I calculate target minus 2 which is 7.
I check if 7 is in the map... it's not, so I add 2 → 0.
Wait... I'm adding the value as the key. But then when I look
up target - num, I need to find the index, not the value!
Oh, I should be storing num → index, not index → num!"
Strategy 7: Binary Search Your Code
When to use: Code fails but you don't know where.
How:
- Add a print statement in the middle
- Check if it's correct up to that point
- If yes, bug is in second half
- If no, bug is in first half
- Repeat until you find the exact line
Example:
def binary_search(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
print(f"Checking range [{left}, {right}]") # Debug
mid = (left + right) // 2
print(f"Mid = {mid}, value = {nums[mid]}") # Debug
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Strategy 8: Pattern Recognition
When to use: Problem reminds you of something but you can't place it.
Common patterns:
"Find all combinations" → Backtracking
"Shortest path" → BFS
"Longest/shortest substring with condition" → Sliding window
"Count ways to..." → DP
"Find in sorted array" → Binary search
"Track min/max efficiently" → Heap or monotonic stack
"Group/count frequencies" → Hash map
"Unique elements" → Set
"Recent items" → Queue
"Undo operations" → Stack
Strategy 9: Component Testing
When to use: Complex solution with multiple parts.
How:
- Test each function separately
- Verify each component works in isolation
- Then test integration
Example:
# Test helper separately
def is_palindrome(s):
return s == s[::-1]
# Test: is_palindrome("aba") → True
# Test: is_palindrome("abc") → False
# Then use in main function
def partition(s):
result = []
def backtrack(start, current):
if start == len(s):
result.append(current[:])
return
for end in range(start + 1, len(s) + 1):
substring = s[start:end]
if is_palindrome(substring): # Using tested helper
current.append(substring)
backtrack(end, current)
current.pop()
backtrack(0, [])
return result
Strategy 10: The 80/20 Solution
When to use: Time is running out.
How:
- Solve the main case that covers 80% of situations
- Acknowledge edge cases exist
- Show you know what's missing
Example:
def solution(arr):
# Handle the main case
result = process_main_case(arr)
# Acknowledge what's missing:
# "This doesn't handle negative numbers yet, but we could
# add a check at the start to handle those separately"
return result
Emergency Strategies
If you're at 30+ minutes and really stuck:
1. Verbalize the struggle:
"I'm finding this challenging. Let me try a different angle..."
2. Ask for guidance:
"Would it help if I explained my thought process so far?"
3. Pivot to what you know:
"I'm stuck on the optimal solution, but let me show you
the brute force approach to prove I understand the problem..."
4. Show meta-problem-solving:
"In a real scenario, I'd look at similar problems in the
codebase or discuss with teammates. Could we do that here?"
Key Takeaway
Getting unstuck is a skill, not luck. The best engineers don't get stuck less—they get unstuck faster. They try multiple strategies, communicate constantly, and aren't afraid to change approaches. Practice these strategies and you'll spend less time stuck and more time solving.