Mastering the Two Pointers Technique in Python (With Easy Examples)
Tags: Python β’ Programming β’ DSA β’ Algorithms
Author: Annet A
When I first started solving coding problems, I noticed that many array and string questions looked different but could actually be solved using the same approach: Two Pointers.
Instead of using nested loops and checking every possible pair of elements, the two pointers technique allows us to solve many problems efficiently in O(n) time.
In this blog, I'll explain what the Two Pointers technique is, when to use it, and some common patterns with examples.
What is the Two Pointers Technique?
The Two Pointers technique uses two indices (pointers) that move through a data structure such as an array or string.
Instead of processing one element at a time, we use two positions that move based on certain conditions until we reach the desired result.
This often reduces the time complexity from O(nΒ²) to O(n).
When Should You Use Two Pointers?
The technique is useful when working with:
- β
Sorted arrays
- β
Strings
- β
Palindromes
- β
Removing duplicates
- β
Pair sum problems
- β
Reversing arrays
- β
Sliding window variations
Whenever you see words like:
- Pair
- Sorted
- Remove duplicates
- Reverse
- Palindrome
think about whether the Two Pointers approach can simplify the solution.
Types of Two Pointer Patterns
There are several common patterns.
1. Opposite Direction Pointers
One pointer starts from the beginning and the other starts from the end.
Left Right
β β
[1, 2, 3, 4, 5]
The pointers move toward each other.
Common Problems
- Valid Palindrome
- Two Sum II
- Reverse String
- Container With Most Water
Example
s = list("hello")
left = 0
right = len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
print("".join(s))
Output
olleh
Time Complexity: O(n)
Space Complexity: O(1)
2. Same Direction Pointers (Fast and Slow)
Both pointers move from left to right.
The fast pointer explores every element while the slow pointer keeps track of the correct position.
Slow Fast
β β
[1, 1, 2, 2, 3]
Common Problems
- Remove Duplicates from Sorted Array
- Move Zeroes
- Remove Element
Example
nums = [1, 1, 2, 2, 3]
left = 0
for right in range(1, len(nums)):
if nums[left] != nums[right]:
left += 1
nums[left] = nums[right]
print(nums[:left + 1])
Output
[1, 2, 3]
Time Complexity: O(n)
Space Complexity: O(1)
3. Slow and Fast Pointer
This is another variation where one pointer moves slower than the other.
Usually,
slow += 1
fast += 2
Common Problems
- Detect Cycle in Linked List
- Find Middle of Linked List
- Happy Number
Note: This pattern is primarily used with Linked Lists rather than arrays.
Example: Two Sum II
Given a sorted array, find two numbers whose sum equals the target.
numbers = [2, 7, 11, 15]
target = 9
left = 0
right = len(numbers) - 1
while left < right:
current = numbers[left] + numbers[right]
if current == target:
print(left, right)
break
elif current < target:
left += 1
else:
right -= 1
Output
0 1
Notice how we never use nested loops.
Advantages
- β
Easy to understand
- β
Reduces time complexity
- β
Often converts O(nΒ²) solutions into O(n)
- β
Uses constant extra space
Limitations
- Works best with sorted data.
- Doesn't apply to every array problem.
- Choosing pointer movement correctly is important.
Tips to Identify Two Pointer Problems
Ask yourself these questions:
- Is the array sorted?
- Am I searching for a pair?
- Can I avoid nested loops?
- Can I process elements from both ends?
- Can one pointer track the answer while another explores?
If the answer is Yes, the Two Pointers technique is worth considering.
Final Thoughts
The Two Pointers technique is one of the most important problem-solving patterns in Data Structures and Algorithms. Once you understand when and how to move the pointers, many coding interview problems become much easier.
I recently practiced this technique by solving problems like Remove Duplicates from Sorted Array, Merge Sorted Array, Valid Palindrome, and Two Sum II. Each problem helped me recognize different pointer movement patterns and improved my confidence in solving array and string problems efficiently.
Mastering this technique is a great step before learning more advanced patterns like Sliding Window, which builds upon similar ideas while handling subarrays and substrings.
β If you found this article helpful, consider sharing it with fellow developers.
Happy Coding! π
β Annet A