The Two Pointers technique uses two pointers to solve problems efficiently. These pointers typically move through an array or linked list in a specific way to find a solution. The setup is simple: a left pointer and a right pointer, both starting at different indices of the array. As we process the data, we move these pointers inward or outward based on conditions specific to the problem.
Opposite-direction pointers use a left pointer at the beginning and a right pointer at the end of an array. The pointers move toward each other based on comparing their values. If we're looking for a target sum, we move right when the sum is too large and leftwhen it's too small.
Another pattern is sliding window, where both pointers move in the same direction while maintaining a specific window size. It's useful for finding subarrays with certain properties, but this page focuses on opposite-direction pointers.
The algorithm works by comparing values at two different positions and moving based on what we find. We start with a left pointer at the beginning (0) and a right pointer at the end (length - 1). At each step, we compare the values and move one of the pointers inward based on what we're looking for.
The pointers keep moving until they meet in the middle or we find our solution. This technique is space-efficient because it only needs two variables, and it's time-efficient since we process each element at most once. Because we don't use any extra data structures, the approach is ideal for problems that require comparing elements from different positions.
index 0) and one at the end (index length - 1) of an array. Some problems start the pointers at specific positions based on the constraints.Opposite-direction pointers typically run inside a while loop until the pointers meet. The pattern works best when you need to compare elements from opposite ends of sorted data. In sorted arrays, moving pointers has predictable effects: moving right always gives a smaller value, while moving left gives a larger one. That predictability is what makes it easy to home in on a target.
class Solution:
def twoPointers(self, numbers: List[int], target: int) -> List[int]:
# Step 1: Initialize two pointers
left, right = 0, len(numbers) - 1
# Step 2: Move the pointers
while left < right:
# Step 3: Compare and process
total = numbers[left] + numbers[right]
if total < target:
left += 1
elif total > target:
right -= 1
# Step 4: Terminate (target found)
else:
return [left + 1, right + 1]
# Step 4: Terminate (when loop ends)
return []Palindrome problems are another natural fit for Two Pointers because they require comparing characters from both ends of a string. By checking whether characters match as we move inward, we can validate palindromes without storing or comparing the entire string up front.
Two Pointers is one of the most reliable patterns for solving array, string, and linked list problems efficiently. Here are a few tips for implementing it well and avoiding the common pitfalls:
The two-pointers technique converts a lot of "try every pair" brute force into clean linear scans. Work through these to internalize convergent (left/right) pointers, fast/slow write pointers, and the trickier variants where the two-pointer logic stitches into sliding window or DP:
Completed | Title | Status | Notes | Solution | |
|---|---|---|---|---|---|
Easy | |||||
Easy | |||||
Easy | |||||
Easy | |||||
Medium | |||||
Medium | |||||
Medium | |||||
Medium | |||||
Hard | |||||
Hard | |||||
Hard | |||||
Hard |