The Two Pointers Algorithm is a versatile technique used in solving array and string manipulation problems, especially when dealing with sorted arrays or linked lists. It is a crucial tool for developers and competitive programmers due to its efficiency in solving problems with optimal time and space complexity.
Why is the Two Pointers Algorithm Required?
Consider a scenario where you have a sorted array, and you need to find a pair of elements whose sum equals a target value. A brute-force approach would involve using two nested loops, resulting in a time complexity of O(n^2). However, the Two Pointers Algorithm can solve this problem with a time complexity of O(n), making it a more efficient solution.
What is the Two Pointers Algorithm?
In simple terms, the Two Pointers Algorithm involves two pointers, typically starting at different positions, moving towards each other or in the same direction, based on certain conditions, to solve a problem. This algorithm is particularly effective in reducing the time complexity of problems that seem to require nested loops.
Implementing Two Pointers Algorithm in Python
Here’s a simple Python implementation of the Two Pointers Algorithm to find a pair of elements in a sorted array whose sum equals a target value:
def two_sum(arr, target):
left, right = 0, len(arr) - 1
while left < right:
current_sum = arr[left] + arr[right]
if current_sum == target:
return [arr[left], arr[right]]
elif current_sum < target:
left += 1
else:
right -= 1
return None
Problems Solved Using Two Pointers Algorithm
1. Removing Duplicates from a Sorted Array
Problem Statement:
Given a sorted array, remove the duplicates in-place such that each element appears only once and return the new length.
Solution Explanation:
We use two pointers: one to iterate over the array (j
) and the other (i
) to keep track of the position to insert the unique element. If a unique element is found, it is placed at the position of the second pointer, and the second pointer is incremented.
Python Solution:
def remove_duplicates(nums):
if not nums:
return 0
i = 0
for j in range(1, len(nums)):
if nums[j] != nums[i]:
i += 1
nums[i] = nums[j]
return i + 1
Time Complexity:
O(n) where n is the length of the array.
2. 3 Sum Question
Problem Statement:
Given an integer array nums
, return all the unique triplets [nums[i], nums[j], nums[k]]
such that i != j
, i != k
, and j != k
, and nums[i] + nums[j] + nums[k] == 0
.
Solution Explanation:
We sort the array and then, for each element, use two pointers to find pairs whose sum is the negative of that element. This ensures that the overall sum is zero. We also handle duplicates by skipping over them.
Python Solution:
def three_sum(nums):
nums.sort()
result = []
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, len(nums) - 1
while left < right:
current_sum = nums[i] + nums[left] + nums[right]
if current_sum == 0:
result.append([nums[i], nums[left], nums[right]])
left += 1
right -= 1
while left < right and nums[left] == nums[left - 1]:
left += 1
while left < right and nums[right] == nums[right + 1]:
right -= 1
elif current_sum < 0:
left += 1
else:
right -= 1
return result
Time Complexity:
O(n^2) where n is the length of the array.
3. Trapping Rainwater Question
Problem Statement:
Given n
non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Solution Explanation:
We maintain two pointers at both ends of the array and move them towards each other, calculating the trapped water at each step based on the minimum of the maximum heights encountered so far from both ends.
Python Solution:
def trap(height):
if not height:
return 0
left, right = 0, len(height) - 1
left_max, right_max = height[left], height[right]
water_trapped = 0
while left < right:
if height[left] < height[right]:
left += 1
left_max = max(left_max, height[left])
water_trapped += left_max - height[left]
else:
right -= 1
right_max = max(right_max, height[right])
water_trapped += right_max - height[right]
return water_trapped
Time Complexity:
O(n) where n is the length of the array.
Conclusion
The Two Pointers Algorithm is a powerful technique for solving a variety of problems related to arrays and strings, particularly when dealing with sorted data structures. By understanding and mastering this algorithm, developers and competitive programmers can significantly optimize their solutions, achieving optimal time and space complexities.