Two Pointers
Notes and typical questions for two pointers algorithm
Notes
Check if the question requires manipulating the array in place. If not, maybe having a new array can resolve it quickly.
Typical Questions
Other 2 Pointers Problems
LC 977. Squares of a Sorted Array
🔴 LC 76. Minimum Window Substring
LC 438. Find All Anagrams in a String
This is also listed under HashMap, my LC submission's time complexity is O(n)
🌟 🔴 LC 962. Maximum Width Ramp
This problem can also be resolved by monotonic stack (see that section)
Optimal Solution. TC: O(n), SC: O(n)
🌟 🔴 LC 2863. Maximum Length of Semi-Decreasing Subarrays
This question is the same as LC 962
Approach 1: Monotonix Stack. TC: O(n), SC: O(n)
Approach 2: 2 pointers +
rightMinarray. TC: O(n), SC: O(n)
⚪ LC 696. Count Binary Substrings
Optimal Answer. TC: O(n), SC: O(1)
Strings Match
LC 392. Is Subsequence
Method 1: 2 pointers. Its performance is better DP and it's super easy to implement;
Optimal Answer. TC: O(n), SC: O(1)
🟠 Method 2: DP. Need to realize it's very similar to LC 1143...
⚪ LC 2337. Move Pieces to Obtain a String
Optimal Answer. TC: O(n), SC; O(1)
⚪ LC 408. Valid Word Abbreviation
Optimal Answer. TC: O(n), SC: O(1)
N Sum Problems
LC 167. Two Sum II - Input Array Is Sorted
It's the foundation of LC 15. 3Sum
Optimal Answer. TC: O(n), SC: O(1)
🌟 LC 15. 3Sum
Although "2 sum" can be solved by
HashMap, this 3 sum is actually a 3 pointers problem, it's hard to dedup result without sorting input array
LC 16. 3Sum Closest
It's similar to LC 15 and easier than it.
Optimal Answer. TC: O(n2), SC: O(1)
LC 1925. Count Square Sum Triples
Optimal Answer. TC: O(n2), SC: O(1)
LC 11. Container With Most Water
This is a two-pointer problem (variant of LC 167), but it is easily mistaken for a monotonic stack solution.
Optimal Answer. TC: O(n), SC: O(1)
The widest container (using first and last line) is a good candidate, because of its width. Its water level is the height of the smaller one of first and last line. All other containers are less wide and thus would need a higher water level in order to hold more water. The smaller one of first and last line doesn't support a higher water level and can thus be safely removed from further consideration. if h[i], h[j], where h[i]==h[j], are at maximum width, then for any other pair of heights with narrower width, the min height would need to be taller than both h[i] and h[j]. So NEITHER i or j is a valid contender for future maximums at a narrower widthand you can actually increment/decrement both. You can change the code to check for equal heights and do i++ and j-- and verify.
Merge Elements
⚪ LC 88. Merge Sorted Array
It’s easy to overlook that the for loop can be exited early.
Optimal Answer. TC: O(m+n), SC: O(1)
Delete/Overwrite Elements
Notes
Fast and slow pointers are useful for questions related to moving/removing items in an array. The fast pointer is used for exploring the array. The slow pointer is used to point to the index that can store value when the fast pointer points to the expected value.
For moving element, consider it in 2 ways: moving target value or moving items that are not target values
Check if the question requires keeping the array in the same order at the end
When swapping f/s pointer items, always introduce temp value to avoid exceptions in corner cases (LC 283)
LC 26. Remove Duplicates from Sorted Array
Optimal Answer. TC: O(n), SC: O(1)
⚪ LC 80. Remove Duplicates from Sorted Array II
It's easy to miss a corner case (if you just compare
nums[f]andnums[f-2])The optimal solution is more logical than the solution I came up with by myself (although TC and SC are the same)
Optimal Answer. TC: O(n), SC: O(1)
LC 27. Remove Element
LC 443. String Compression
Optimal Answer. TC: O(n), SC: O(1)
⚪ LC 283. Move Zeroes
Optimal Answer. TC: O(n), SC: O(1)
Sliding Window - General
⚪ LC 643. Maximum Average Subarray I
Optimal Answer; TC: O(n), SC: O(1)
LC 1456. Maximum Number of Vowels in a Substring of Given Length
Optimal Answer; TC: O(n), SC: O(1)
⚪ LC 3350. Adjacent Increasing Subarrays Detection II
My Answer. TC: O(n) with multiple passes, SC: O(n)
Optimal Answer. TC: O(n), SC: O(1)
Sliding Window - Subarray/Substring Search Meeting With Requirements
Notes
Two-pointers are also useful when you need to explore a set of subarrays/substrings that meet certain conditions in a given input array/string and calculate results while exploring subarrays. For this kind of question, you usually need to use a fast point to explore the array and move the left pointer when the subarray does not meet the condition.
🧩 Sliding Window with Aggressive Shrinking
Notes
You may need to use
whileloop to move the left pointer until the subarray meets the condition.
LC 3. Longest Substring Without Repeating Characters
Approach 1: Normal 2 pointers.
Answer. TC: O(2∗n)=O(n), SC: O(1)
👍 ⚪ Approach 2: Optimized 2-pointers. Reduce the inside
whileloop from the outsideforloop. If the window has duplicates, We can move the left pointer directly to the right element of the duplicated one. Since this way will skip removing elements fromMap, we need to ensure the index of duplicates gets fromMapis within the window.Optimal Answer. TC: O(n), SC: O(1)
🌟 ⚪ LC 209. Minimum Size Subarray Sum
Optimal Answer. TC: O(n), SC O(1)
🔴 LC 904. Fruit Into Baskets
🔴 LC 567. Permutation in String
Be careful that there are 2 invalid cases (1. character is not in the target string, 2. character is in the target string but already occurred in windows previously)
if it is the 2nd invalid case, after taking actions, it may become a valid case!
Therefore, we should always check if it is a valid case at the end of each iteration
🔴 LC 3346. Maximum Frequency of an Element After Performing Operations I
I made some progress. I realized the input array needs to be sorted first, and get an O(n2) idea for the 1st case below, but then I got stuck.
2 cases for central point (the value that elements get updated to)
It's an existing element
After sorting, for each element
ein the array, there is a technique to find the number of elements within the range[e-k,e+k]in O(n) by scanning the array once.
It's a value that does not exist in the input array
Optimal Answer. TC: O(n∗logn), SC: O(n)
⚪ LC 2762. Continuous Subarrays
There is another optimal answer that only uses 2 pointers without
TreeMap. Since it has the same TC and SC as my answer and it's more complicated to understand, I did not use it.Let n be the size of input, and k be the size of
TreeMap. Since k should always <= 3 based on the requirement of the question, we can treat k as a constantTC: O(n∗logk)=>O(n)
SC: O(k)=>O(1)
🔴 LC 30. Substring with Concatenation of All Words
Be careful about comparing
Integer!!!The inner loop uses the sliding window idea.
Given n as the length of
s, a as the length ofwords, and b as the length of each word:TC: O(a+n∗b), SC: O(a+b)
🌟 🔴 LC 76. Minimum Window Substring
Common mistake when simply using the normal sliding window idea
Pitfall: Cannot simply move the left pointer when the right pointer points to such a
char c(String t has c with number k, and we already see k times ofcin the current window). Reason is that it's possible to have k+1 times ofcin the final answer window. For example, s="abbc", t="abc"Solution: Core idea to resolve concerns above: Once you have a valid window, aggressively move the left pointer until it becomes invalid.
Answer
👍 Approach 1 with core idea above: Optimal Answer. TC: O(n), SC: O(1)
Approach 2 with an alternative idea: Answer. TC: O(n), SC: O(1)
🟠 LC 2106. Maximum Fruits Harvested After at Most K Steps
Approach 1 with TreeMap (my own solution)
Answer. TC : O(nlogn), SC: O(n)
Approach 2 with Binary Search
Implementation trick: Use
prefixSum[n+1], which meansprefix[i]represents the sum of elements in the half-open range[0, i)(i.e., before indexi).Answer. TC: O(n+klogn), SC: O(n)
👍 Approach 3 with Sliding Window
Optimal Answer. TC: O(n), SC: O(1)
🧩 Sliding Window with Non-Aggressive Shrinking
Notes
You may NOT use
whileloop to move the left pointer until the subarray meets the condition and NOT shrink the window below the max window size found previously.
🌟 ⚪ LC 1004. Max Consecutive Ones III
Think it this way instead: Find the max window which includes at most k 0's
Straightforward idea: Have a 2 loops. Outer loop to explore array. When the window is invalid, the inner loop is used to keep reducing windows from the left side until it becomes valid. Answer. TC: O(n), SC: O(1)
Improved idea: No need for the inner loop. when the window becomes invalid,
j - ieffectively represents the current max window size. We don’t need to keep shrinking the window from the left until it becomes valid; we only need to maintain the current size and slide the window forward. Once the window becomes valid again after a shift, we can naturally continue expanding it. Answer. TC: O(n), SC: O(1)
⚪ LC 1493. Longest Subarray of 1's After Deleting One Element
Basically same as above LC 1004
Optimal Answer. TC: O(n), SC: O(1).
🔴 LC 424. Longest Repeating Character Replacement
The idea of not shrinking window size is similar to LC 1004
When finding the first valid window, assume the window size is
land the max frequency of characters within this window ismaxFreq. Valid window meansl-maxFreq <= kIn the next round,
Increase windows by moving
endindex to the right by 1.If new
l+1length window becomes invalid now, we just need to movestartindex to right by 1 and update the frequency map.Then the window size becomes to
lagain but this newlsize window may be INVALID andmaxFreqmay be STALE.However, we do NOT care about these 2 issues. Since we want to find the max window, we can just use the previous valid max window size to scan the array.
If there is a larger valid window size (>
l), there must be a largermaxFreqbecause this equationl-maxFreq <= k. Only whenmaxFreqbecomes larger,lcan be larger as well.That's also why we do NOT need to consider decreasing
maxFreqwhen movingstartindex and do NOT care if it is stale. We ONLY care and want to find a largermaxFreq
Last updated