Three Sum
Solution
Jump Game (Greedy Strategy)
-
Optimal:
time, space. -
The Logic: Use a single loop to track the
max_reachindex. As you walk through, updatemax_reach = max(max_reach, i + nums[i]). -
When to fail: If your current index
i > max_reach, you've hit a dead endreturn False. -
Greedy Paradigm: "Make the best local choice right now (extend reach as far as possible) and never look back."
Two Sum (Hash Map Strategy)
-
Optimal:
time, space. -
The Logic: Look backward instead of forward. Keep a dictionary of
seennumbers (value -> index). -
The Math: For every number, calculate its
complement = target - num. If the complement is inseen, you've found your pair! If not, store the current number and move on. -
Trade-off: You sacrifice a little memory (
space) to buy massive speed gains (dropping from to ).
3Sum (Sorting + Two Pointers)
-
Optimal:
time, auxiliary space. -
The Logic ("Lock and Slide"):
-
Sort the array first (groups duplicates, enables logic-based pointer movement).
-
Lock the first number
ausing an outer loop. -
Place two pointers at the ends of the remaining subarray: Left (
l) and Right (r). -
Slide pointers inward: If the sum is too big, move
rleft (r -= 1). If the sum is too small, movelright (l += 1).
-
-
Handling Duplicates:
-
Skip identical numbers for the locked index:
if i > 0 and a == nums[i-1]: continue. -
Skip identical numbers for the left pointer after finding a jackpot:
while nums[l] == nums[l-1].
-
-
Crucial Rule (Indices vs. Values): Triplets like
[-1, -1, 2]are perfectly legal as long as the numbers come from different physical indices (i != j != k).
Quick Interview Mindset Reminders
-
Memory vs. Time: Always mention trade-offs. (e.g., "We use a hash map to get
time at the cost of space.") -
Grid Traversals (BFS/DFS): Know how to navigate a 2D matrix (like Number of Islands), as AI data often lives in 2D grids/images.
-
Top-K Elements: Know how to use a Min-Heap / Priority Queue (crucial for LLM token sampling and recommendation systems).
Summary
- So, to conclude:
- Organize and sort the array
- De-duplicate elements before settling on your first value (a)
- Then move to sub loop and set the
Lpointer toi+1from the current position andRpointer to the end of the array.- You can shift the
Lpointer if the combination of elements (threesum) is less than 0 - You can shift the
Rpointer if the combination of elements (threesum) is greater than 0
- You can shift the
- Finally, you end the loop once the three sum is equal to 0 and return the list of elements that produced it.
Implementation
- Optimal Implementation:
- Time complexity - O(n
) - Sorting the array takes O(
log ) - The outer loop runs
times. For each iteration, the inner two-pointer whileloop scans the remainder of the array intime. .
- Sorting the array takes O(
- Space complexity = O(1)
- Time complexity - O(n
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
res = []
nums.sort()
for i, a in enumerate(nums):
if i > 0 and a == nums[i - 1]:
continue
l, r = i + 1, len(nums) - 1
while l < r:
threesum = a + nums[l] + nums[r]
if threesum > 0:
r -= 1
elif threesum < 0:
l += 1
else:
res.append([a, nums[l], nums[r]])
l += 1
while nums[l] == nums[l - 1] and l < r:
l += 1
return res