Code Templates
This page provides reusable two pointers templates that you can adapt for various problems. Review the Concept Guide first for core understanding.
Opposite Direction Template
Use when working with sorted arrays to find pairs, check palindromes, or solve container problems.
function twoPointersOpposite(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left < right) {
const sum = arr[left] + arr[right];
if (sum === target) {
return [left, right]; // Found
} else if (sum < target) {
left++; // Need larger sum
} else {
right--; // Need smaller sum
}
}
return [-1, -1]; // Not found
}def two_pointers_opposite(arr: list, target: int) -> list:
left, right = 0, len(arr) - 1
while left < right:
total = arr[left] + arr[right]
if total == target:
return [left, right] # Found
elif total < target:
left += 1 # Need larger sum
else:
right -= 1 # Need smaller sum
return [-1, -1] # Not foundpublic int[] twoPointersOpposite(int[] arr, int target) {
int left = 0, right = arr.length - 1;
while (left < right) {
int sum = arr[left] + arr[right];
if (sum == target) {
return new int[]{left, right}; // Found
} else if (sum < target) {
left++; // Need larger sum
} else {
right--; // Need smaller sum
}
}
return new int[]{-1, -1}; // Not found
}vector<int> twoPointersOpposite(vector<int>& arr, int target) {
int left = 0, right = arr.size() - 1;
while (left < right) {
int sum = arr[left] + arr[right];
if (sum == target) {
return {left, right}; // Found
} else if (sum < target) {
left++; // Need larger sum
} else {
right--; // Need smaller sum
}
}
return {-1, -1}; // Not found
}func twoPointersOpposite(arr []int, target int) []int {
left, right := 0, len(arr)-1
for left < right {
sum := arr[left] + arr[right]
if sum == target {
return []int{left, right} // Found
} else if sum < target {
left++ // Need larger sum
} else {
right-- // Need smaller sum
}
}
return []int{-1, -1} // Not found
}def two_pointers_opposite(arr, target)
left, right = 0, arr.length - 1
while left < right
sum = arr[left] + arr[right]
if sum == target
return [left, right] # Found
elsif sum < target
left += 1 # Need larger sum
else
right -= 1 # Need smaller sum
end
end
[-1, -1] # Not found
endSame Direction Template
Use for removing duplicates, partitioning arrays, or in-place modifications.
function removeDuplicates(nums) {
if (nums.length === 0) return 0;
let slow = 0; // Position for next unique element
for (let fast = 1; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1; // Length of unique portion
}def remove_duplicates(nums: list) -> int:
if not nums:
return 0
slow = 0 # Position for next unique element
for fast in range(1, len(nums)):
if nums[fast] != nums[slow]:
slow += 1
nums[slow] = nums[fast]
return slow + 1 # Length of unique portionpublic int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int slow = 0; // Position for next unique element
for (int fast = 1; fast < nums.length; fast++) {
if (nums[fast] != nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1; // Length of unique portion
}int removeDuplicates(vector<int>& nums) {
if (nums.empty()) return 0;
int slow = 0; // Position for next unique element
for (int fast = 1; fast < nums.size(); fast++) {
if (nums[fast] != nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1; // Length of unique portion
}func removeDuplicates(nums []int) int {
if len(nums) == 0 { return 0 }
slow := 0 // Position for next unique element
for fast := 1; fast < len(nums); fast++ {
if nums[fast] != nums[slow] {
slow++
nums[slow] = nums[fast]
}
}
return slow + 1 // Length of unique portion
}def remove_duplicates(nums)
return 0 if nums.empty?
slow = 0 # Position for next unique element
(1...nums.length).each do |fast|
if nums[fast] != nums[slow]
slow += 1
nums[slow] = nums[fast]
end
end
slow + 1 # Length of unique portion
endCode Breakdown
flowchart TD
subgraph Opposite["Opposite Direction"]
O1[left = 0, right = n-1] --> O2{left < right?}
O2 -->|Yes| O3[Compare elements]
O3 --> O4{Condition met?}
O4 -->|Yes| O5[Record result]
O4 -->|No| O6[Move appropriate pointer]
O5 --> O6
O6 --> O2
O2 -->|No| O7[Done]
end
subgraph Same["Same Direction"]
S1[slow = 0, fast = 1] --> S2{fast < n?}
S2 -->|Yes| S3{Different element?}
S3 -->|Yes| S4[slow++, copy element]
S3 -->|No| S5[Skip]
S4 --> S6[fast++]
S5 --> S6
S6 --> S2
S2 -->|No| S7[Return slow + 1]
end
Key Variables
- left/right: Pointers moving toward each other
- slow/fast: Pointers moving in same direction at different speeds
- result: Accumulator for found pairs or modified array length
Variations
Three Sum (Fixed + Two Pointers)
function threeSum(nums) {
nums.sort((a, b) => a - b);
const result = [];
for (let i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] === nums[i - 1]) continue;
let left = i + 1, right = nums.length - 1;
while (left < right) {
const sum = nums[i] + nums[left] + nums[right];
if (sum === 0) {
result.push([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 < 0) {
left++;
} else {
right--;
}
}
}
return result;
}def three_sum(nums: list) -> list:
nums.sort()
result = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, len(nums) - 1
while left < right:
total = nums[i] + nums[left] + nums[right]
if total == 0:
result.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]: left += 1
while left < right and nums[right] == nums[right - 1]: right -= 1
left += 1; right -= 1
elif total < 0:
left += 1
else:
right -= 1
return resultpublic List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1, right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
result.add(Arrays.asList(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 < 0) {
left++;
} else {
right--;
}
}
}
return result;
}vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> result;
for (int i = 0; i < nums.size() - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1, right = nums.size() - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
result.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 < 0) {
left++;
} else {
right--;
}
}
}
return result;
}func threeSum(nums []int) [][]int {
sort.Ints(nums)
result := [][]int{}
for i := 0; i < len(nums)-2; i++ {
if i > 0 && nums[i] == nums[i-1] { continue }
left, right := i+1, len(nums)-1
for left < right {
sum := nums[i] + nums[left] + nums[right]
if sum == 0 {
result = append(result, []int{nums[i], nums[left], nums[right]})
for left < right && nums[left] == nums[left+1] { left++ }
for left < right && nums[right] == nums[right-1] { right-- }
left++; right--
} else if sum < 0 {
left++
} else {
right--
}
}
}
return result
}def three_sum(nums)
nums.sort!
result = []
(0...nums.length - 2).each do |i|
next if i > 0 && nums[i] == nums[i - 1]
left, right = i + 1, nums.length - 1
while left < right
sum = nums[i] + nums[left] + nums[right]
if sum == 0
result << [nums[i], nums[left], nums[right]]
left += 1 while left < right && nums[left] == nums[left + 1]
right -= 1 while left < right && nums[right] == nums[right - 1]
left += 1; right -= 1
elsif sum < 0
left += 1
else
right -= 1
end
end
end
result
endPractice
Ready to apply these templates? Head to the Practice Problems page.
Pro Tip: The key to mastering two pointers is recognizing which variation fits the problem. Sorted input usually means opposite direction; in-place modification usually means same direction.