Two Sum
Use a hash map to store each number’s index. For every element, check if the complement (target - current) exists in the map.
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
seen = {}
for idx, val in enumerate(nums):
complement = target - val
if complement in seen:
return [seen[complement], idx]
seen[val] = idx
Group Anagrams
Group words by their sorted character signature. All anagrams produce the same sorted string.
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
groups = {}
for s in strs:
key = ''.join(sorted(s))
groups.setdefault(key, []).append(s)
return list(groups.values())
Longest Consecutive Sequence
Convert the list to a set for O(1) lookups. Only start counting from numbers that are the beginning of a sequence (i.e., num - 1 is not in the set).
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
num_set = set(nums)
max_len = 0
for n in num_set:
if n - 1 not in num_set:
length = 1
while n + length in num_set:
length += 1
max_len = max(max_len, length)
return max_len
Move Zeroes
Use two pointers: one tracks the next position for a non-zero element, the other scans the array.
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
write = 0
for read in range(len(nums)):
if nums[read] != 0:
nums[write], nums[read] = nums[read], nums[write]
write += 1
Container With Most Water
Start with the widest container. Move the pointer at the shorter line inward, as moving the taller one cannot increase the area.
class Solution:
def maxArea(self, height: List[int]) -> int:
left, right = 0, len(height) - 1
max_area = 0
while left < right:
width = right - left
h = min(height[left], height[right])
max_area = max(max_area, width * h)
if height[left] < height[right]:
left += 1
else:
right -= 1
return max_area
3Sum
Sort the array. Fix the first number and use two pointers for the remaining two. Skip duplicates to avoid repeated triplets.
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
result = []
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i-1]:
continue
l, r = i + 1, len(nums) - 1
while l < r:
total = nums[i] + nums[l] + nums[r]
if total < 0:
l += 1
elif total > 0:
r -= 1
else:
result.append([nums[i], nums[l], nums[r]])
while l < r and nums[l] == nums[l+1]:
l += 1
while l < r and nums[r] == nums[r-1]:
r -= 1
l += 1
r -= 1
return result
Trapping Rain Water
For each bar, the water it can trap depends on the maximum height to its left and right. Use dynamic programming or two pointers to compute this efficiently.
Longest Substring Without Repeating Characters
Maintain a sliding window with a hash map storing the last index of each character. Shrink the window from the left when a duplicate is found.
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char_index = {}
left = 0
max_len = 0
for right, char in enumerate(s):
if char in char_index and char_index[char] >= left:
left = char_index[char] + 1
char_index[char] = right
max_len = max(max_len, right - left + 1)
return max_len
Find All Anagrams in a String
Use a fixed-size sliding window with a frequency array. Compare the window’s character count with that of the pattern.
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
if len(s) < len(p):
return []
p_count = [0] * 26
s_count = [0] * 26
for c in p:
p_count[ord(c) - ord('a')] += 1
result = []
for i in range(len(s)):
s_count[ord(s[i]) - ord('a')] += 1
if i >= len(p):
s_count[ord(s[i - len(p)]) - ord('a')] -= 1
if s_count == p_count:
result.append(i - len(p) + 1)
return result
Maximum Subarray
Kadane’s algorithm: track the maximum sum ending at each position. Reset the current sum to zero if it becomes negative.
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
best = float('-inf')
current = 0
for x in nums:
current += x
best = max(best, current)
if current < 0:
current = 0
return best
Merge Intervals
Sort intervals by start time. Merge overlapping intervals by updating the end of the last merged interval.
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x: x[0])
merged = []
for interval in intervals:
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
merged[-1][1] = max(merged[-1][1], interval[1])
return merged
Rotate Array
Reverse the entire array, then reverse the first k elements and the remaining elements separately.
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k %= n
def reverse(start, end):
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
reverse(0, n - 1)
reverse(0, k - 1)
reverse(k, n - 1)
Product of Array Except Self
Compute prefix products from the left, then multiply by suffix products from the right in a second pass.
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
result = [1] * n
for i in range(1, n):
result[i] = result[i-1] * nums[i-1]
suffix = 1
for i in range(n - 2, -1, -1):
suffix *= nums[i+1]
result[i] *= suffix
return result
First Missing Positive
Use the input array as a hash table. Place each number x at index x - 1 if possible. The first mismatch gives the answer.
Intersection of Two Linked Lists
Align the two lists by having both pointers traverse A + B nodes. They will meet at the intersection or both become null.
class Solution:
def getIntersectionNode(self, headA, headB):
pa, pb = headA, headB
while pa != pb:
pa = pa.next if pa else headB
pb = pb.next if pb else headA
return pa
Reverse Linked List
Iteratively reverse pointers using three variables: previous, current, and next.
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
curr = head
while curr:
next_temp = curr.next
curr.next = prev
prev = curr
curr = next_temp
return prev
Detect Cycle in Linked List
Floyd’s cycle detection: use slow and fast pointers. If they meet, a cycle exists.
Remove Nth Node From End of List
Use two pointers. Advance the fast pointer n steps first, then move both until the fast pointer reaches the end.
Binary Tree Inorder Traversal
Recursive approach: traverse left subtree, visit root, then traverse right subtree.
Maximum Depth of Binary Tree
Recursively compute the depth as 1 + max(left_depth, right_depth).
Invert Binary Tree
Swap left and right children recursively.
Symmetric Tree
Check if the left subtree is a mirror of the right subtree using a helper functon.
Level Order Traversal
Use a queue to process nodes level by level.
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
from collections import deque
q = deque([root])
result = []
while q:
level = []
for _ in range(len(q)):
node = q.popleft()
level.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
result.append(level)
return result
Balanced Binary Tree
During depth calculation, return -1 if any subtree is unbalanced.
Construct BST from Sorted Array
Recursively pick the middle element as the root to ensure balance.
Validate BST
Perform inorder traversal and verify the result is strictly increasing.
Kth Smallest Element in BST
Inorder traversal yields elements in sorted order; return the k-th visited node.
Permutations
Use backtracking: choose an unused element, recurse, then unchoose.
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
result = []
def backtrack(path):
if len(path) == len(nums):
result.append(path[:])
return
for num in nums:
if num not in path:
path.append(num)
backtrack(path)
path.pop()
backtrack([])
return result
Subsets
At each step, decide whether to include the current element. Use a start index to avoid duplicates.
Combination Sum
Backtrack with repetition allowed. Sort candidates to enable early termination.
Valid Parentheses
Use a stack. Push opening brackets; pop and match when encountering a closing bracket.
class Solution:
def isValid(self, s: str) -> bool:
stack = []
mapping = {')': '(', '}': '{', ']': '['}
for char in s:
if char in mapping:
top = stack.pop() if stack else '#'
if mapping[char] != top:
return False
else:
stack.append(char)
return not stack
Min Stack
Maintain a main stack and an auxiliary stack that tracks the minimum at each state.
Decode String
Use a stack to handle nested structures. When encountering ], pop until [, repeat the substring, and push back.
Top K Frequent Elements
Count frequencies, then sort by frequency and take the top k.
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
from collections import Counter
count = Counter(nums)
return [item for item, _ in count.most_common(k)]
Best Time to Buy and Sell Stock
Track the minimum price so far and compute the maximum profit at each day.
class Solution:
def maxProfit(self, prices: List[int]) -> int:
min_price = float('inf')
max_profit = 0
for price in prices:
min_price = min(min_price, price)
max_profit = max(max_profit, price - min_price)
return max_profit
Jump Game
Track the farthest reachable index. If it exceeds the last index, return true.
Climbing Stairs
Dynamic programming: dp[i] = dp[i-1] + dp[i-2].
House Robber
dp[i] = max(dp[i-1], dp[i-2] + nums[i]).
Coin Change
Unbounded knapsack: dp[amount] = min(dp[amount - coin] + 1) for all coins.
Word Break
dp[i] is true if there exists j < i such that dp[j] is true and s[j:i] is in the dictionary.
Longest Increasing Subsequence
For each element, check all previous elements to extend the LIS ending at that position.
Maximum Product Subarray
Track both maximum and minimum products at each position due to negative values.
Partition Equal Subset Sum
Subset sum problem: check if half the total sum can be formed.
Edit Distance
dp[i][j] represents the minimum operations to convert word1[:i] to word2[:j].
Single Number
XOR all numbers; duplicates cancel out.
class Solution:
def singleNumber(self, nums: List[int]) -> int:
result = 0
for n in nums:
result ^= n
return result
Majority Element
Boyer-Moore Voting Algorithm: maintain a candidate and count. The majority element survives.
Sort Colors
Dutch National Flag problem: use three pointers to partition 0s, 1s, and 2s.
Next Permutation
Find the first decreasing element from the right, swap with the smallest larger element to its right, then reverse the suffix.
Find the Duplicate Number
Treat the array as a linked list with cycle. Use Floyd’s algorithm to find the entrance.