Two Pointers II (Advanced)
Two Pointers II (Advanced)
1. 3Sum
Mental Model:
- This is an evolution of the pair-sum problem.
- We fix one element (
nums[i]) and use two pointers (left,right) to find pairs that complete the target0 - nums[i]. - The key trick is to sort the array first — so duplicates are adjacent and the search becomes ordered.
Flow:
- Sort the array.
- Iterate through each element
i. - Use two pointers from both ends of the remaining array to find complement pairs.
- Skip duplicates carefully to avoid redundant triplets.
Think of it as:
- Fix one → find two using “move inward” pointers.
C++ Solution:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
int n = nums.size();
for (int i = 0; i < n; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // skip duplicates
int left = i + 1, right = n - 1;
int target = -nums[i];
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) {
res.push_back({nums[i], nums[left], nums[right]});
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++; right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return res;
}
};
Revision Tip:
- Always sort first — it enables ordered pointer movement and easy duplicate handling.
- If you see a “find triplet/pair that sums to X” → think “fix one + two-pointer scan.”
- Two pointers here are guided by sum comparison, not just traversal.
2. Container With Most Water
Mental Model:
- You have vertical lines on the x-axis. The area is defined by width * min(height[left], height[right]).
- The naive approach is O(n²), but the two-pointer approach optimizes it:
- Start with two ends (left, right).
- Compute the current area.
- Move the pointer pointing to the shorter line, because the limiting height can only increase by moving that one.
This is a classic case of:
- “Shrink search space intelligently while maintaining the possibility of a larger area.”
class Solution {
public:
int maxArea(vector<int>& height) {
int left = 0;
int right = height.size() - 1;
int maxArea = INT_MIN;
while (left < right) {
maxArea = max(maxArea, ((right - left) * min(height[left], height[right])));
if (height[left] < height[right]) { left++; }
else {right--; }
}
return maxArea;
}
};
Revision Tip:
- The core pattern: move the limiting pointer.
- Think in terms of “what can increase the result next.”
- This idea generalizes to problems like “trap rain water,” “minimum window,” etc.