</> MAANG.io
coding interview ยท 101

Foundations

Master coding interviews with comprehensive coverage of data structures, algorithms, and problem-solving techniques. Progress from fundamentals to advanced topics with expertly curated content.

0/255 solved 0% complete

Array Deletion and Modification

What is this?

Picture a row of theater seats that's bolted to the floor โ€” you can't yank a chair out and leave a gap, the seats don't move. So instead of "deleting" someone, you ask everyone you want to keep to slide down and fill the front rows neatly, then put up a sign saying "the show only uses the first N seats." That's the whole idea: you tidy the keepers into the front of the array and report how many there are, without ever needing a second room.

flowchart TD A["Read pointer scans every element"] --> B["Is this one a keeper?"] B --> C["Yes: copy it to the write pointer, advance write"] B --> D["No: skip it, leave write where it is"] C --> E["Everything before write is the clean result"] D --> E

๐Ÿ’ก Fun fact: This "two pointers, one slow and one fast" cleanup is the same core move that real databases like Cassandra and RocksDB run constantly under the hood, in a step called compaction โ€” quietly rewriting their files to squeeze out stale and duplicate records so your queries stay fast.

๐Ÿ”“ The problem in this chapter is free. Sign in with Google or Microsoft to start solving.


The one-line idea: you can't truly delete from a fixed-size array โ€” there's no hole to remove. So you overwrite in place using a write pointer that lags behind a read pointer, and report a new logical length. Master that one reflex and a whole family of "remove / compact / filter" problems collapses into a single clean pass.


1. What "in-place deletion" really means

An array is a contiguous block of memory of fixed size. There is no remove button that shrinks it โ€” the slots don't go anywhere. "Deleting" really means rearranging the survivors into a clean prefix and telling the caller how long that prefix is. The garbage past it is left as scratch.

The engine is two indices walking the same array:

Read (fast) and write (slow) pointers compacting an array in place

The read pointer inspects each element; the write pointer only advances when the read pointer finds something worth keeping. Because the write pointer can never overtake the read pointer, every survivor is copied at most once โ€” so the whole compaction is a single O(n) sweep with O(1) extra space.

โš ๏ธ The classic beginner trap is to "delete" by shifting the tail left every time you drop an element. That's O(n) work per deletion โ†’ O(nยฒ) overall. Overwriting with a write pointer is the fix: leave the dead elements in place and march the survivors over them.


2. Where you'll actually meet this

In-place compaction is a hot inner loop in real infrastructure, not a worksheet exercise:

  • LSM-tree compaction (Cassandra, RocksDB, LevelDB). Merging sorted SSTable runs writes out a compacted run, dropping superseded/duplicate keys as it streams โ€” a read/write-pointer dance over sorted data.
  • Kafka log compaction. A segment is rewritten keeping the latest record per key; obsolete copies are squeezed out during the rewrite.
  • Columnar & vectorized analytics (Arrow, Parquet, DuckDB). Filtering or run-length encoding a column compacts surviving values into a dense output vector in place.
  • Networking. Coalescing retransmitted, sequence-sorted packets or collapsing adjacent duplicate ACKs before handing data up the stack.
  • Finance. Compacting a sorted tick/quote stream so the order-book builder sees each price level once.
  • Retail / warehouse ops. Dedping a pick-list sorted by bin so a picker visits each location once.

If a problem says remove, delete in place, compact, filter out, keep only, move all X to the end, or return the new length โ€” this chapter's toolkit applies.


3. The deletion toolkit (patterns to recognise)

  1. Read/write two pointers. read scans; write marks where the next survivor lands. Copy nums[read] โ†’ nums[write] and bump write only when the element passes your keep-test. This is the spine of nearly every in-place removal.
  2. Overwrite, never shift. Dropping an element costs nothing โ€” you simply don't advance write. Avoid the O(nยฒ) "shift the tail left" trap.
  3. Return the length, not the array. The contract is a number k plus a valid prefix nums[0..k-1]. Everything after k is intentionally undefined.
  4. Exploit structure to cheapen the keep-test. On a sorted array, "is this a duplicate?" becomes "is it equal to the previous survivor?" โ€” one comparison, no hash set, O(1) space.

4. A 30-second worked example (compact a sorted run)

Buffer [2, 2, 2, 7, 7, 8]. Keep only the first copy of each run, in place.

Worked example: compacting the sorted run [2 2 2 7 7 8] to [2 7 8], length 3

No second buffer, no shifting โ€” one walk, two pointers, a length out. That single reflex is the heart of the first problem in this chapter.


5. Problems in this chapter

โ–ถ Remove Duplicates from Sorted Array

A sorted buffer arrives with consecutive repeats (think retried telemetry reports); collapse each run to one copy in place and return how many distinct values remain. Teaches the read/write two-pointer reflex, why sortedness kills the need for a hash set, and how overwriting beats shifting.
Pattern: lagging write pointer. Target: O(n) time, O(1) space.

(More modification problems โ€” remove element, move zeroes, remove duplicates II โ€” slot in here as the chapter grows; they all reuse tools #1โ€“#3 above.)


6. Common pitfalls ๐Ÿšซ

  • Shifting the tail on every delete โ€” turns an O(n) sweep into O(nยฒ). Overwrite with a write pointer instead.
  • Returning the array instead of the length โ€” the grader reads k slots; the tail is scratch and may legitimately hold stale values.
  • Forgetting the empty array โ€” guard len == 0 before touching nums[0].
  • Reaching for a hash set on sorted input โ€” that's O(n) space you don't need; adjacency already encodes "seen it."
  • Advancing the write pointer unconditionally โ€” it must move only when an element survives the keep-test, or you'll copy duplicates forward.

7. Key takeaways

  1. You can't shrink a fixed array โ€” deletion = compacting survivors into a prefix + returning its length.
  2. The read/write two-pointer sweep does it in O(n) time, O(1) space, copying each survivor at most once.
  3. Overwrite, don't shift โ€” dropping an element is free; the O(nยฒ) shift loop is the trap.
  4. Lean on structure: a sorted array makes the keep-test a single neighbour comparison โ€” no extra space.
  5. The same lagging-pointer pattern generalises to remove element, move zeroes, and dedup II โ€” and it's exactly how production compaction pipelines stream a cleaned result.

Sign in to MAANG.io

Use your Google or Microsoft account โ€” no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.