Two pointers and sliding window: patterns with examples
Two pointers and sliding windows turn O(n²) array and string problems into O(n). Learn when and how to use each.

Many array and string problems ask about subarrays, substrings or pairs. A brute-force solution checks all possibilities in O(n²) or worse. Two techniques often cut that to O(n): two pointers and the sliding window.
Technique 1: two pointers
Use two indexes that move through the data to avoid nested loops. There are two common shapes.
Opposite ends, moving inward
Works well on sorted arrays or when checking symmetry.
Problem: in a sorted array, find two numbers that add up to a target.
function twoSumSorted(nums, target) {
let left = 0, right = nums.length - 1;
while (left < right) {
const sum = nums[left] + nums[right];
if (sum === target) return [left, right];
if (sum < target) left++; // need a bigger sum
else right--; // need a smaller sum
}
return [];
}
// Time O(n), space O(1)
Because the array is sorted, each step safely discards one candidate. That is why it works.
Problem: is a string a palindrome (ignoring non-letters)? Compare from both ends, moving inward.
Other uses: the container with most water, 3Sum (sort, fix one number, then two pointers on the rest), reversing in place.
Same direction: slow and fast
Both pointers move forward at different paces or roles.
Problem: remove duplicates from a sorted array in place.
function removeDuplicates(nums) {
if (nums.length === 0) return 0;
let write = 1;
for (let read = 1; read < nums.length; read++) {
if (nums[read] !== nums[read - 1]) nums[write++] = nums[read];
}
return write; // length of the unique part
}
// Time O(n), space O(1)
The read pointer scans; the write pointer marks where the next kept value goes. The same idea moves zeroes to the end or filters values.
Fast and slow on linked lists: moving one pointer twice as fast finds the middle, and detects a cycle (Floyd's algorithm).
Technique 2: sliding window
A window is a contiguous range of the array or string. You slide it by adding the new element on the right and removing the old one on the left, updating a running value instead of recomputing everything.
Fixed-size window
Problem: the maximum sum of any subarray of size k.
function maxSumK(nums, k) {
let sum = 0;
for (let i = 0; i < k; i++) sum += nums[i];
let best = sum;
for (let i = k; i < nums.length; i++) {
sum += nums[i] - nums[i - k]; // add the new, drop the old
best = Math.max(best, sum);
}
return best;
}
// Time O(n), space O(1)
Variable-size window
The window expands on the right, and shrinks from the left whenever a rule is broken.
Problem: the length of the longest substring without repeating characters.
function longestUnique(s) {
const lastSeen = new Map();
let left = 0, best = 0;
for (let right = 0; right < s.length; right++) {
const ch = s[right];
if (lastSeen.has(ch) && lastSeen.get(ch) >= left) {
left = lastSeen.get(ch) + 1; // jump past the repeat
}
lastSeen.set(ch, right);
best = Math.max(best, right - left + 1);
}
return best;
}
// Time O(n), space O(min(n, alphabet))
A general template for variable windows:
left = 0
for right in range(n):
add item[right] to window state
while window is invalid:
remove item[left] from window state
left += 1
update the answer using the window [left..right]
More problems: smallest subarray with sum at least S (positive numbers), longest substring with at most K distinct characters, minimum window substring, permutation in string.
When to use which
| Clue in the problem | Likely technique |
|---|---|
| Sorted array, find a pair or triplet | Two pointers from both ends |
| In-place modification, remove or partition | Read/write pointers |
| Linked list middle or cycle | Fast and slow pointers |
| Contiguous subarray or substring, with a size or a condition | Sliding window |
| Subarray sum with possibly negative numbers | Prefix sums + hash map (window can fail) |
Sliding window with a shrinking rule relies on a monotonic condition: adding elements keeps moving the window state in one direction. With negative numbers that can break.
Common mistakes
- Off-by-one errors at the window edges. Decide whether
rightis inclusive and test small cases by hand. - Forgetting to update the window state when moving
left. - Using a window when the data are not contiguous (then think hash map, DP or sorting).
- Not handling empty input, or
klarger than the array.
Practice problems
Valid Palindrome, Two Sum II (sorted), 3Sum, Container With Most Water, Remove Duplicates from Sorted Array, Best Time to Buy and Sell Stock, Longest Substring Without Repeating Characters, Minimum Window Substring.
Takeaway: if a problem asks about pairs in sorted data or contiguous ranges, try two pointers or a sliding window. Both aim to visit each element a constant number of times, giving O(n).
Interview prep and DSA series, Part 1 (core patterns): 3 of 5. Previous: Arrays and hash maps: the interview patterns you must know.


