Master the systematic approach to acing coding interviews with this comprehensive step-by-step framework.
These are the steps you should follow when in a data structures and algorithm interview:
Ask questions to ensure you understand the constraints and requirements.
Consider boundary conditions and special scenarios.
Purposes:
Explain your thought process as you code.
Custom test cases / walking through your code before clicking run (it is ok to test during development!)
Responsibility (like proofreading a paper)
The interviewer doesn't know if you're a responsible programmer or not who looks at code before submitting PR or kicking off expensive builds. The interview is where you show them.
(can be done in clarifying questions, but not recommended to commit upfront in case you can't think of an approach to align with that)
Given an array of 0s, 1s, and 2s, return a sorted array.
# input -> [2, 0, 2, 1, 1, 0]
# output -> [0, 0, 1, 1, 2, 2]This brute force approach would fail unless you were going for an internship at not a top tier tech company (i.e. not Meta, Google, OpenAI but instead Target, CVS, Capital One)
def sort_colors_brute_force(arr:list[int]) -> list[int]:
"""
Brute-force method to sort array of 0s, 1s, and 2s.
Not in-place: builds and returns a new sorted list.
"""
# Step 1: Count occurrences of 0s, 1s, and 2s
count_0 =count_1 =count_2 =0
for numin arr:
if num== 0:
count_0 +=1
elif num== 1:
count_1 +=1
elif num== 2:
count_2 +=1
# Step 2: Reconstruct sorted list
return [0]* count_0+ [1]* count_1+ [2]* count_2This is what you need to produce to pass as jr, mid-level and senior:
low -> 0
mid -> 0
high -> len(input) - 1
traversing the array using mid
if arr[mid] === 0 swap arr[mid] with arr[low], increment mid and low
if arr[mid] == 1: just move mid forward
if arr[mid] == 2: swap arr[mid] with arr[high], decrement high. not increment mid in this casedef sort_colors(arr):
# Initialize three pointers
low =0# For placing 0s
mid =0# Current element under consideration
high =len(arr)- 1# For placing 2s
# Traverse the array with mid pointer
while mid<= high:
if arr[mid] ==0:
# Swap current element with the element at low
arr[low],arr[mid]= arr[mid], arr[low]
low +=1
mid +=1
elif arr[mid] ==1:
# 1s are in the middle, just move forward
mid +=1
else:
# Swap current element with the element at high
arr[mid],arr[high]= arr[high], arr[mid]
high -=1# Move high pointer left
# Do not increment mid here because we need to check the swapped value
return arrWhy?
You only traverse the array once, using a while loop with a mid pointer.
At every step, you do one of three operations:
Although high might get moved many times, each index in the array is looked at only once by mid. Even when we swap with high, we are bringing in a new element to inspect — but that new element has not been processed yet. So we never reprocess an element.
Conclusion:
Each element is processed at most once. Therefore, the total number of operations is proportional to the number of elements, i.e., O(n), where n is the length of the array.
Why?
Conclusion:
The space usage does not increase with input size. So the algorithm has constant space complexity, or O(1).
This version generalizes the Dutch National Flag algorithm to handle any number of distinct known values (e.g., 0–k), assuming:
It works by maintaining a boundary pointer for each value.
def k_partition_sort(nums:list[int], value_order:list[int]):
"""
In-place sorting of known k distinct values using generalized Dutch National Flag logic.
Args:
nums: list[int] - input list containing only values from value_order.
value_order: list[int] - the ordered list of distinct values (e.g., [0,1,2] or [0,1,2,3,4])
"""
from collectionsimport defaultdict
# Step 1: Create boundary map
boundaries =defaultdict(int)# Maps each value to where its region ends
n =len(nums)
i =0
while i< n:
val =nums[i]
# Find where to insert this value
insert_pos =0
for vin value_order:
if v== val:
break
insert_pos +=boundaries[v]
# If insert position < current index, we need to shift the middle block
if insert_pos!= i:
# Save current value
temp =nums[i]
# Shift elements right
for jin reversed(range(insert_pos, i)):
nums[j +1]= nums[j]
# Insert the value at correct boundary
nums[insert_pos]= temp
# Update boundaries for current and all greater values
found =False
for vin value_order:
if v== val:
found =True
if found:
boundaries[v]+= 1
i +=1
# Example with 3 values
nums1 =[2, 0, 2, 1, 1, 0]
k_partition_sort(nums1,[0, 1, 2])
print("Sorted (3-value):", nums1)# Output: [0, 0, 1, 1, 2, 2]
# Example with 5 values
nums2 =[4, 2, 0, 1, 3, 2, 4, 0, 1, 3]
k_partition_sort(nums2,[0, 1, 2, 3, 4])
print("Sorted (5-value):", nums2)# Output: [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]For each of the n elements, shifting may require O(k) operations (up to k boundaries checked + shifting range).
Uses O(k) space for the boundaries map. No auxiliary array used.