The Converging Pointer Pattern: Efficient Pair Searching in Arrays
Imagine you’re at a bustling farmers’ market, and you want to pick two fruits whose combined price exactly matches your budget. You glance at the price tags from both ends of the row and adjust your picks until you hit the perfect match. Surprisingly, this simple intuition is exactly what the converging two-pointer approach does in arrays.
If you’ve read our previous post on the two-pointer pattern, you know it involves using two pointers to explore an array efficiently.Today, we dive deeper into a specific subpattern: target sum using converging pointers.
Converging Pointer Pattern
The Converging Pointer Pattern involves two pointers starting at opposite ends of a sorted array. The pointers move toward each other to efficiently find a condition — often a target sum or pair meeting some requirement.
Problem
Given a sorted array of numbers, find whether any two numbers sum up to a target value.
For instance, in the array [1, 2, 4, 6, 8], can you find two numbers that add up to 10?
Core Idea
Move two pointers through the array in a way that each element is considered at most once. Compare the sum of the elements at the two pointers with the target:
This approach ensures we don’t check the same pair twice and find the result efficiently.
Think of it like two explorers walking from opposite ends of a bridge, meeting in the middle once they’ve found the right gap.
step-by-step flow
Start
|
v
Initialize left = 0 (points to 1), right = 4 (points to 8)
|
v
Step 1: total = input[left] + input[right] = 1 + 8 = 9
|
+-- Is total == target (10)? --> No
+-- Is total < target? --> Yes --> move left pointer right (left++)
|
v
Step 2: left = 1 (points to 2), right = 4 (points to 8)
|
v
total = 2 + 8 = 10
|
+-- Is total == target? --> Yes --> return true
|
v
End: target sum found (2 + 8 = 10)Solution
fun targetSumConvergencePointer(input: IntArray, target: Int): Boolean {
if (input.size < 2) return false
var left = 0
var right = input.size - 1
while (left < right) {
val total = input[left] + input[right]
when {
total == target -> {
return true
}
total > target -> {
right--
}
else -> {
left++
}
}
}
return false
}Time Complexity
O(n) – We go through the array just once, with the two pointers moving toward each other.
Space Complexity
Conclusion
The converging two-pointer approach shows how a simple idea—starting two pointers at opposite ends and moving them based on a condition—can solve problems like finding a pair with a target sum efficiently.
With this pattern, you learn to think in terms of adjusting your exploration based on the current state, which is a skill that extends to many other array and sequence problems.
Once you’ve mastered converging pointers, the next trick is the sliding window. Imagine a flexible window moving across the array or string, expanding or shrinking to capture exactly what you need. In the next post, we’ll dive deeper into this pattern—until then, keep practicing and happy coding!
