The array is already sorted, so duplicates sit next to each other. A slow / fast pointer pair compacts the uniques to the front in place: slow marks where the next unique value goes, fast scans for it. Return the new length k.
Compact a sorted array so each value appears once, doing it in place, and return the count k of uniques. nums = [0,0,1,1,1,2,2,3,3,4] → k = 5 with nums[:5] = [0,1,2,3,4]. The tail beyond kis don't-care.
slow write head at the end of the unique prefix; whenever fast finds a value != nums[slow], bump slow and copy it forward. No extra array, no set.0.slow = 0. nums[0] is always the first unique, so the prefix already has one element.fast from 1. Compare nums[fast] to nums[slow] — the last value we kept.slow then set nums[slow] = nums[fast]. Duplicates are simply skipped.slow + 1 — the length of the unique prefix.nums[fast] against nums[slow] (the last kept value), NOT against nums[fast - 1]. With this exact write order they happen to coincide here, but anchoring on slowis the version that generalizes (e.g. "allow each value at most twice"). Also remember to slow++ before writing, never after.You must read every element at least once, so O(n) time is unavoidable. The slow/fast trick does it with a constant number of extra variables — no set, no copy — which is the whole point of the "in place" requirement.
slow is always the write head; fast is the reader.slow = 0: nums[0] is always the first unique value. Scan with fast from index 1.1function removeDuplicates(nums: number[]): number {2 if (nums.length === 0) return 0;3▶ let slow = 0; // last write position of a unique value4▶ for (let fast = 1; fast < nums.length; fast++) {5 if (nums[fast] !== nums[slow]) { // found a new value6 slow++; // advance the write head7 nums[slow] = nums[fast]; // write it forward8 }9 }10 return slow + 1; // count of unique values = k11}
function removeDuplicates(nums: number[]): number {
if (nums.length === 0) return 0;
let slow = 0; // last write position of a unique value
for (let fast = 1; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) { // found a new value
slow++; // advance the write head
nums[slow] = nums[fast]; // write it forward
}
}
return slow + 1; // count of unique values = k
}0 before touching any index.nums[0] is automatically unique, so slow starts at 0: the unique prefix already contains one value.fast walks from 1. We compare against nums[slow], the last value we decided to keep. Equal ⇒ duplicate ⇒ do nothing.nums[fast] differs, advance slow first, then copy nums[fast] into the freed slot. The prefix nums[0..slow] stays strictly increasing.slow is the index of the last unique, so slow + 1 is the count k. The grader reads only nums[0..k-1].slow and fast, mutating the input array in place.nums[fast] against nums[slow - 1] and start slow at 2 — the same write-head idea with a window of two.slow++ before the write?" The slot at slow already holds a kept value; the next unique belongs at slow + 1.kare don't-care, so leaving the stale values is fine.function removeDuplicates(nums: number[]): number {
if (nums.length === 0) return 0;
let slow = 0; // last write position of a unique value
for (let fast = 1; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) { // found a new value
slow++; // advance the write head
nums[slow] = nums[fast]; // write it forward
}
}
return slow + 1; // count of unique values = k
}slow and fast, mutating the input array in place.Ignore the sortedness, dedupe with a Set, then copy unique values back. Works on unsorted input too, but allocates O(n) memory and violates the in-place spirit.
function removeDuplicates(nums: number[]): number {
const seen = new Set<number>();
let k = 0;
for (const x of nums) {
if (!seen.has(x)) {
seen.add(x);
nums[k++] = x;
}
}
return k;
}| sorted array, remove duplicates in place | slow/fast two pointers |
| "return new length k, O(1) space" | write head + return slow + 1 |
| duplicates are adjacent (sorted) | compare nums[fast] vs nums[slow] |
| "filter in place, keep order" | slow = write index, fast = reader |
if (nums.length === 0) return 0;
let slow = 0;
for (let fast = 1; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1;