If you are preparing for coding interviews, Two Pointer and Sliding Window are two of the most important array and string problem-solving techniques you should master.
At first, these problems can look completely different. You might be asked to find a pair with a target sum, check whether a string is a palindrome, remove duplicates from an array, find the longest substring, or calculate the maximum value inside a subarray.
However, many of these problems share the same underlying idea:
Instead of repeatedly examining the same elements, use pointers to move through the data efficiently.
This can reduce an algorithm from O(n²) to O(n) in many cases.
In this guide, we will learn:
- What the Two Pointer technique is
- Different Two Pointer patterns
- Opposite-direction pointers
- Slow and Fast pointers
- Merging two arrays using pointers
- Divide and Conquer with Two Pointers
- What Sliding Window is
- Fixed-size and variable-size windows
- When to use Two Pointer vs Sliding Window
- Important LeetCode problems to practice
- Common mistakes and interview tips
Table of Contents
- What Is the Two Pointer Technique?
- Pattern 1: Two Pointers From Opposite Ends
- Pattern 2: Slow and Fast Pointers
- Pattern 3: Two Pointers From Two Arrays
- Pattern 4: Split and Merge / Divide and Conquer
- What Is Sliding Window?
- Fixed-Size Sliding Window
- Variable-Size Sliding Window
- Two Pointer vs Sliding Window
- Important LeetCode Problems
- Common Mistakes
- How to Recognize These Patterns in Interviews
- Conclusion
What Is the Two Pointer Technique?
The Two Pointer technique is an algorithmic approach where we maintain two indices or references while traversing an array, string, linked list, or another data structure.
Instead of using nested loops to compare every possible pair of elements, we move the pointers according to the conditions of the problem.
For example:
1 2 3 4 5 6 7 8
L R
Here:
L represents the left pointer.R represents the right pointer.- The pointers move according to the problem's requirements.
The key advantage is that each pointer usually moves through the input only a limited number of times.
Therefore, many Two Pointer solutions achieve:
Time Complexity: O(n)
Space Complexity: O(1)
although the exact complexity depends on the problem.
The Two Pointer technique can be broadly organized into four useful patterns:
- Pointers moving from opposite ends
- Slow and Fast pointers
- Pointers processing two arrays
- Split, process, and merge using Divide and Conquer
Pattern 1: Two Pointers From Opposite Ends
This is probably the most recognizable Two Pointer pattern.
We initialize one pointer at the beginning and another at the end:
Array:
[1, 2, 3, 4, 5, 6, 7, 8]
↑ ↑
L R
Then we move the pointers toward each other.
This pattern is particularly useful when:
- The array is sorted.
- We need to find pairs.
- We need to compare values from both ends.
- We need to reverse or swap elements.
- We need to process a structure symmetrically.
The source material describes this pattern as starting with pointers at the left and right ends and moving them toward the center while processing elements.
Example: Two Sum II
Suppose we have a sorted array:
[2, 7, 11, 15]
and the target is:
9
Start with:
L = 0
R = 3
Check:
2 + 15 = 17
Since the sum is too large, move R to the left.
2 + 11 = 13
Still too large.
Move R again:
2 + 7 = 9
We found the answer.
Why does this work?
Because the array is sorted.
If:
nums[L] + nums[R] > target
we know that increasing L would only make the sum larger, so we move R.
Similarly, if:
nums[L] + nums[R] < target
we move L forward.
This eliminates a huge number of unnecessary comparisons.
Two Pointer Pattern for 3Sum
The same idea can be extended to problems involving three elements.
For 3Sum, we first sort the array.
Then we fix one element:
i
↓
[-4, -1, -1, 0, 1, 2]
and use two pointers for the remaining portion:
i L R
↓ ↓ ↓
[-4, -1, -1, 0, 1, 2]
Now the problem becomes a Two Sum problem inside the remaining array.
This is a very important interview pattern:
Fix one element + apply Two Pointers to the remaining elements.
The same idea can be extended to 4Sum and other k-sum variations.
Trapping Rain Water
Another important application is the Trapping Rain Water problem.
We maintain:
left
right
leftMax
rightMax
and process the array from both ends.
The intuition is that the amount of water trapped at a position depends on the maximum height available from both sides.
Instead of repeatedly calculating left and right maximums, the Two Pointer approach maintains this information while moving toward the center.
This allows the problem to be solved in:
O(n) time
O(1) extra space
Next Permutation
Next Permutation is another important Two Pointer problem.
The general idea is:
- Find the first decreasing element from the right.
- Find a larger element from the right.
- Swap them.
- Reverse the suffix.
For example:
1 2 3
The next permutation is:
1 3 2
The reversal of the suffix is itself a Two Pointer operation because we can reverse the range using pointers at both ends.
Reversing and Swapping
Two pointers are also extremely useful when modifying an array or string in-place.
Consider reversing:
hello
We start with:
L = 0
R = 4
Swap:
h <-> o
Then:
L++
R--
Continue until:
L >= R
This gives an O(n) time and O(1) extra-space solution.
Common problems using this idea include:
- Valid Palindrome
- Reverse String
- Reverse Vowels of a String
- Valid Palindrome II
- Reverse Only Letters
- Remove Element
- Sort Colors
- Flipping an Image
- Squares of a Sorted Array
- Sort Array by Parity
- Sort Array by Parity II
- Pancake Sorting
- Reverse Prefix of Word
- Reverse String II
- Reverse Words in a String
The source notes include these problems under the reversing/swapping category.
Pattern 2: Slow and Fast Pointers
The second major pattern is Slow and Fast Pointers.
Unlike the opposite-end pattern, both pointers generally start from the same side.
Slow
↓
[1, 2, 3, 4, 5, 6, 7]
Fast
↓
The fast pointer moves faster than the slow pointer.
For example:
slow = slow.next
fast = fast.next.next
This technique is particularly powerful for linked lists.
The source describes this pattern as using two pointers that move at different speeds, where the faster pointer provides information used by the slower pointer.
Linked List Cycle Detection
The classic example is Linked List Cycle.
Suppose a linked list looks like:
1 → 2 → 3 → 4
↑ ↓
└─────┘
We use:
slow = slow.next
fast = fast.next.next
If a cycle exists, eventually the fast pointer will meet the slow pointer.
This is known as Floyd's Cycle Detection Algorithm.
Why does it work?
Imagine two runners moving around a circular track.
One runs faster than the other.
Eventually, the faster runner must catch up with the slower runner.
The same principle works inside a cyclic linked list.
Find the Duplicate Number
Find the Duplicate Number is a particularly interesting problem because it can be transformed into a cycle detection problem.
Instead of treating the numbers simply as values in an array, we can interpret them as pointers.
Then Floyd's cycle detection algorithm can be applied.
This gives a solution with:
Time: O(n)
Space: O(1)
The source groups this problem with cyclic detection and slow/fast pointer techniques.
Other Slow and Fast Pointer Problems
Important problems include:
Linked List
- Linked List Cycle
- Linked List Cycle II
- Remove Nth Node From End of List
- Rotate List
- Reorder List
- Palindrome Linked List
Cyclic Detection
- Find the Duplicate Number
- Circular Array Loop
These problems form an excellent progression for learning slow and fast pointers.
Pattern 3: Two Pointers From Two Arrays
Another important variation occurs when we have two arrays or lists.
Instead of using two pointers inside one array, each pointer belongs to a different data structure.
For example:
Array A: [1, 3, 5, 7]
↑
i
Array B: [2, 4, 6, 8]
↑
j
We compare:
A[i]
B[j]
and move one or both pointers according to the problem.
This is especially useful for:
- Merging sorted arrays
- Finding intersections
- Comparing strings
- Subsequence problems
- Processing two sorted sequences
The source describes this category as processing two arrays or lists using individual pointers.
Merge Sorted Array
Suppose:
A = [1, 3, 5]
B = [2, 4, 6]
We maintain one pointer for each array.
A: 1 3 5
↑
B: 2 4 6
↑
Compare:
1 < 2
So we take 1.
Then:
3 > 2
So we take 2.
Continue until one array is exhausted.
This is the fundamental technique behind merging sorted sequences.
Intersection of Two Arrays
The same technique can be used to find the intersection of two sorted arrays.
For example:
A = [1, 2, 3, 5]
B = [2, 3, 4, 5]
When:
A[i] == B[j]
we found a common element.
If:
A[i] < B[j]
move i.
Otherwise:
B[j] < A[i]
move j.
This avoids comparing every element with every other element.
Comparing Strings Using Two Pointers
Two pointers can also be used when comparing strings.
For example, problems involving:
- Long Pressed Name
- Implement
strStr - Camelcase Matching
- Expressive Words
- Compare Version Numbers
often involve moving through two strings while deciding which pointer should advance.
The source groups these problems under substring/string processing with two independent pointers.
Pattern 4: Split and Merge / Divide and Conquer
The fourth pattern combines Divide and Conquer with Two Pointer processing.
The basic idea is:
Original Array
|
Split into
two parts
/ \
Left Right
\ /
Merge
We first divide the input into smaller parts.
Then we solve the smaller parts independently.
Finally, we use pointer-based processing to combine the results.
This pattern is closely related to Merge Sort.
The source describes this category as splitting a list into two parts and then using a Two Pointer-style merge process to unify the results.
Partition List
Partition List is one problem that can be approached using pointer manipulation to construct the required partitions.
The important lesson is that pointer-based techniques are not limited to arrays.
They can also be extremely powerful when manipulating linked lists.
Sort List
Sort List is a classic linked-list Divide and Conquer problem.
The high-level approach is:
- Find the middle of the linked list.
- Split it into two lists.
- Recursively sort both halves.
- Merge the sorted lists.
Finding the middle commonly uses the slow and fast pointer technique.
Then merging uses two pointers.
So this one problem demonstrates multiple patterns:
Slow/Fast Pointers
+
Divide and Conquer
+
Two Pointer Merge
What Is Sliding Window?
Sliding Window is a technique used to process a contiguous portion of an array or string efficiently.
Think of the window as a frame moving across the input.
For example:
[1, 2, 3, 4, 5, 6, 7, 8]
└───────┘
Window
Instead of recalculating the entire window every time, we update it incrementally.
When the window moves:
[1, 2, 3]
becomes:
[2, 3, 4]
We remove the contribution of 1 and add the contribution of 4.
This can turn an O(n × k) brute-force approach into an O(n) solution.
Fixed-Size Sliding Window
In a Fixed-Size Sliding Window, the window size remains constant.
Suppose:
k = 3
and the array is:
[1, 2, 3, 4, 5, 6]
The windows are:
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
At each step:
- Add the new element.
- Remove the element leaving the window.
- Update the answer.
A common problem pattern is:
Find the maximum/minimum/sum of every subarray of size
k.
Fixed Window Example
Suppose we need the maximum sum of a subarray of size 3.
For:
[2, 1, 5, 1, 3, 2]
Start with:
2 + 1 + 5 = 8
Move the window:
1 + 5 + 1 = 7
Instead of calculating this sum from scratch:
8 - 2 + 1 = 7
Then:
7 - 1 + 3 = 9
So the maximum is:
9
The important idea is:
When the window moves, remove what leaves and add what enters.
Variable-Size Sliding Window
The second major Sliding Window pattern is the Variable-Size Window.
Here the size of the window changes based on a condition.
For example:
while condition is invalid:
move left pointer
and:
move right pointer
to expand the window.
Conceptually:
L
↓
[1, 2, 3, 4, 5]
↑
R
The right pointer expands the window.
The left pointer contracts it when the window violates a condition.
This pattern is extremely common in substring and subarray problems.
The General Variable Window Template
A common structure looks like:
left = 0
for right = 0 to n - 1:
add nums[right] to window
while window is invalid:
remove nums[left]
left++
update answer
The most important part is identifying:
What makes the current window valid or invalid?
That condition determines how the pointers move.
Sliding Window and Caterpillar Method
Sliding Window is sometimes also described as the Caterpillar Method.
The basic movement looks like:
L → → →
R → → →
Both pointers move forward through the array rather than repeatedly starting over.
The source specifically groups several problems under the Sliding Window/Caterpillar Method category.
Examples include:
- Number of Subarrays With Bounded Maximum
- Find K-th Smallest Pair Distance
- Moving Stones Until Consecutive II
- Count Pairs of Nodes
- Count Binary Substrings
- K-diff Pairs in an Array
Sliding Window for Strings
Sliding Window is especially useful for strings.
Typical questions include:
- Longest substring satisfying a condition
- Shortest substring satisfying a condition
- Number of substrings satisfying a condition
- Longest substring with at most K distinct characters
- Frequency-based substring problems
A common approach is to maintain a data structure such as:
HashMap<Character, Integer>
to track the characters currently inside the window.
For example:
"abcabcbb"
[a b c]
↓
Window
When a condition becomes invalid, move the left pointer until the window becomes valid again.
Two Pointer vs Sliding Window
These techniques are closely related, but they are not exactly the same.
| Technique | Typical Structure | Common Use |
|---|---|---|
| Two Pointers | Two indices/references | Pairs, reversing, merging, linked lists |
| Opposite Pointers | Left + Right | Sorted arrays, palindrome, partitioning |
| Slow/Fast | Different pointer speeds | Linked lists, cycle detection |
| Two Arrays | One pointer per input | Merging, intersection, string comparison |
| Sliding Window | Left + Right boundary | Subarrays and substrings |
| Fixed Window | Constant window size | Size-k subarray problems |
| Variable Window | Dynamic window size | Longest/shortest valid range |
A useful way to think about it is:
Sliding Window is essentially a specialized form of the two-pointer idea for maintaining a contiguous range.
How to Recognize Two Pointer Problems
When you see a problem, ask yourself these questions.
Question 1: Is the array sorted?
If yes, immediately consider:
Two Pointers
Especially when the problem asks for:
- Pair sum
- Triplets
- Closest value
- Pairing elements
- Removing duplicates
Question 2: Do I need to compare both ends?
For example:
Is this string a palindrome?
Think:
left →
← right
Question 3: Is it a linked list?
Think about:
slow
fast
Especially for:
- Cycle detection
- Finding the middle
- Finding a node relative to the end
- Reordering a linked list
Question 4: Are there two sorted inputs?
Think:
i → Array A
j → Array B
This is common in:
- Merge
- Intersection
- Subsequence
- String comparison
How to Recognize Sliding Window Problems
Look for words such as:
- Subarray
- Substring
- Contiguous
- Consecutive
- Window
- Longest
- Shortest
- Maximum
- Minimum
- At most K
- Exactly K
Then ask:
Can I maintain the answer for the current range and update it when the range moves?
If yes, Sliding Window may be the right approach.
Important LeetCode Problems to Practice
The following problems form a useful practice roadmap based on the patterns in this guide.
Beginner Two Pointer Problems
Start with:
- Two Sum II – Input Array Is Sorted
- Valid Palindrome
- Reverse String
- Remove Element
- Squares of a Sorted Array
- Sort Array by Parity
- Intersection of Two Arrays
These help you understand basic pointer movement.
Intermediate Two Pointer Problems
Next, practice:
- 3Sum
- Container With Most Water
- Sort Colors
- Valid Palindrome II
- Boats to Save People
- Minimize Maximum Pair Sum in Array
- Find K Closest Elements
- Next Permutation
The source specifically highlights problems such as 3Sum, 4Sum, Boats to Save People, Minimize Maximum Pair Sum, and Next Permutation as important Two Pointer applications.
Advanced Two Pointer Problems
Once comfortable, move to:
- 4Sum
- Trapping Rain Water
- 3Sum With Multiplicity
- Find K-th Smallest Pair Distance
- Last Substring in Lexicographical Order
- Shortest Subarray to Be Removed to Make Array Sorted
Important Sliding Window Problems
For Sliding Window, practice problems such as:
Fixed/Window-Based Problems
- Number of Subarrays With Bounded Maximum
- Count Binary Substrings
- K-diff Pairs in an Array
- Longest Mountain in Array
- Shortest Subarray to Be Removed to Make Array Sorted
The source also includes several advanced problems under its Sliding Window/Caterpillar category.
Other Two Pointer Patterns Worth Practicing
There are several additional problems that may not look like classic Two Pointer problems initially.
Examples include:
- Bag of Tokens
- DI String Match
- Minimum Length of String After Deleting Similar Ends
- Sentence Similarity III
- Find K Closest Elements
- Shortest Distance to a Character
These are useful because interviewers often test whether you can recognize the underlying pattern, rather than simply identify a problem you've seen before.
Advanced Two-Array and Merge Problems
Once you understand the basic two-array pattern, practice:
- Merge Sorted Array
- Heaters
- Find the Distance Value Between Two Arrays
- Intersection of Two Linked Lists
- Intersection of Two Arrays II
- Longest Word in Dictionary Through Deleting
- Long Pressed Name
- Compare Version Numbers
- Camelcase Matching
- Expressive Words
The source organizes these problems around sorted arrays, intersections, string comparison, and related two-pointer techniques.
Divide and Conquer Problems
Finally, connect Two Pointers with Divide and Conquer.
Important problems from this category include:
- Partition List
- Sort List
The source identifies these as the main problems in its split-and-merge/Divide and Conquer category.
Common Two Pointer Mistakes
1. Moving the Wrong Pointer
In a sorted Two Sum problem:
sum < target
usually means the left pointer should move right.
While:
sum > target
usually means the right pointer should move left.
Understanding why the pointer moves is more important than memorizing the code.
2. Forgetting to Sort
Many Two Pointer problems depend on sorted data.
For example:
Two Sum II
3Sum
4Sum
Boats to Save People
may rely on sorted order.
Always check whether sorting is allowed and what complexity it introduces.
3. Incorrect Duplicate Handling
Problems such as:
3Sum
4Sum
Remove Duplicates
often require careful handling of duplicate values.
Don't simply move both pointers without considering repeated elements.
4. Off-by-One Errors
Be careful with:
left <= right
versus:
left < right
The correct condition depends on whether both pointers are allowed to process the same position.
Common Sliding Window Mistakes
1. Not Removing the Left Element
When the window moves:
[1, 2, 3]
to:
[2, 3, 4]
you must remove 1 from your window state.
2. Using the Wrong Window Condition
For variable-size windows, clearly define:
What makes the window valid?
and:
What makes it invalid?
This usually determines the entire algorithm.
3. Shrinking Too Much
When the window becomes invalid, move left only as much as necessary to restore validity.
A Practical Interview Strategy
When you encounter an array or string problem during an interview, use this thought process.
Step 1: Look for brute force
Ask:
What would the obvious solution be?
Usually this reveals the repeated work.
Step 2: Look for ordering
Ask:
Is the input sorted or can I sort it?
If yes, Two Pointers may be useful.
Step 3: Look for a range
Ask:
Am I dealing with a contiguous subarray or substring?
If yes, consider Sliding Window.
Step 4: Look for two sequences
Ask:
Am I processing two arrays, strings, or linked lists simultaneously?
If yes, consider two independent pointers.
Step 5: Look for different speeds
If the problem involves a linked list and asks about:
- Cycles
- Middle
- Relative positions
consider Slow and Fast pointers.
Step 6: Analyze complexity
A good Two Pointer or Sliding Window solution often looks like:
Time: O(n)
Space: O(1)
or:
Time: O(n)
Space: O(k)
when a frequency map or other window state is required.
The Most Important Mental Models
Instead of memorizing dozens of solutions, remember these four mental models.
Mental Model 1: Opposite Ends
L → ← R
Use when processing from both ends.
Mental Model 2: Slow and Fast
S →
F → →
Use when pointers move at different speeds.
Mental Model 3: Two Inputs
A: i →
B: j →
Use when processing two arrays, strings, or lists.
Mental Model 4: Sliding Window
L → [--------] ← R
Use when maintaining a contiguous range.
Final Takeaway
Two Pointer and Sliding Window are not simply coding tricks. They are problem-solving patterns.
The most important thing is learning to recognize when a problem can be transformed from repeated comparisons into controlled pointer movement.
The major patterns to remember are:
1. Opposite-direction pointers
2. Slow and Fast pointers
3. Two pointers across two arrays/lists
4. Split and Merge / Divide and Conquer
5. Fixed-size Sliding Window
6. Variable-size Sliding Window
Once these patterns become familiar, many array, string, and linked-list problems become much easier to approach.
Instead of immediately writing nested loops, train yourself to ask:
Can I solve this by moving two pointers intelligently?
That question alone can turn many O(n²) solutions into O(n) solutions.
And that is why Two Pointer and Sliding Window are essential patterns for DSA and coding interviews.
![]() |
