Remove Duplicates from Sorted Array
- Learn the same direction (read/write) two pointer pattern
- Understand in-place array modification
- Apply the pattern to remove unwanted elements
A sorted array hands you the duplicates for free: every repeat sits directly next to the value it copies. So you never reach for a hash set here, and you never allocate a second array. Two pointers moving the same direction finish the job in one pass, which is the thing that separates this from the converging pointers you used in Two Sum II. One pointer reads ahead. The other tracks where the next keeper belongs, and that read/write split is how you rewrite an array in place without spending a byte of extra space.
Step 1: Understand the Read/Write Pattern
The two cursors behave like editing a document. One reads through the text (the read pointer); the other marks where the next kept character lands (the write pointer). The read cursor touches every position, but the write cursor only advances once you've decided the thing you just read is worth keeping.
[0, 1, 2 | ... unprocessed ...]↑ write pointer (first 3 elements are unique)
Step 2: The Algorithm
The whole loop is this:
write = 0 # Points to last unique element we've writtenfor read in range(1, len(nums)): if nums[read] != nums[write]: # Found a new unique element! write += 1 # Advance write position nums[write] = nums[read] # Copy the unique elementreturn write + 1 # Count of unique elementsWhy compare with nums[write] instead of nums[read-1]? Because nums[write] is always the last unique value we kept. After processing, everything from 0 to write is unique. The original value at read-1 might be a duplicate we skipped!
Step 3: Visual Walkthrough
Try It Yourself
The write pointer only advances when the read pointer finds something different from nums[write]. Return write + 1 (index → count).
Try it yourself
Remove DuplicatesGiven an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once.
The relative order of the elements should be kept the same. Return k after placing the final result in the first k slots of nums.
Constraints:
• 1 <= nums.length <= 3 * 10^4
• -100 <= nums[i] <= 100
• nums is sorted in non-decreasing order
Examples
Input: nums = [1, 1, 2]
Output: 2, nums = [1, 2, _]
Return k=2. First two elements are unique values 1 and 2.
Input: nums = [0,0,1,1,1,2,2,3,3,4]
Output: 5, nums = [0,1,2,3,4,_,_,_,_,_]
Return k=5. Five unique values remain.
Remove Duplicates
Click "Run" to execute your code
Test Cases
[1, 1, 2]Expected: 2[0, 0, 1, 1, 1, 2, 2, 3, 3, 4]Expected: 5[1]Expected: 1Solution
Solution
Take some time to think about the problem before revealing the solution. Try to write the code yourself first - that's where the real learning happens.
Things to Watch Out For
A few mistakes that come up more often than you'd think:
write + 1 so the index becomes a count.2. Comparing with
nums[read-1] instead of nums[write]: After overwriting elements, nums[read-1] might hold a value you already wrote. Always compare with nums[write] to check the last kept unique value.3. Edge cases: Empty array → return 0. Single element → return 1. All duplicates like [7, 7, 7, 7] → write never advances past 0, return 1.
The Read/Write Pattern
One reads, one writes. That split is the workhorse behind almost every in-place array edit. The write pointer owns the clean portion of the array while the read pointer scouts ahead, and swapping in a different keep-condition is all it takes to solve a whole family of these: Remove Element drops one specific value, Remove Duplicates II tolerates two copies of each.
Key Takeaways
- Same direction pointers: one reads, one writes
- Write pointer only advances when we find something to keep
- Sorted array makes duplicates adjacent (easy to detect)
- Return write + 1 for the count
- Pattern adapts: change the "should I keep this?" condition