InterviewPrepKit

Home / Coding / Two Pointers

String Compression

medium Original β†—
Solving tips
  • This is the read/write two-pointer transducer: a read pointer consumes each run, a write pointer emits the compressed output over the same array.
  • State the size argument up front: a run of length L>=2 compresses to 1+digits(L) <= L characters, so write can never overtake read, making in-place safe; target O(n) time, O(1) space.
  • Emit the character alone for runs of length 1 (no count), and for multi-digit lengths write each digit separately via str(run), not the number in one cell.
  • Pitfall: capture the run's character before advancing read, and return write (the compressed length), ignoring the garbage cells past it.

Problem

You are given a list of characters chars. Compress it in place using run-length encoding: replace each maximal run of a repeated character with the character followed by the run’s length β€” except that runs of length 1 get no number. Lengths of 10 or more are written as their individual digit characters (e.g. a run of 12 as becomes 'a', '1', '2').

Overwrite the front of chars with the compressed sequence and return its length. Use O(1) extra space β€” building a separate string is against the rules.

Examples

Example 1

Input:  chars = ["a","a","b","b","c","c","c"]
Output: 6, chars = ["a","2","b","2","c","3", ...]

Runs aa, bb, ccc become a2, b2, c3.

Example 2

Input:  chars = ["a"]
Output: 1, chars = ["a"]

A single character gets no count.

Example 3

Input:  chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
Output: 4, chars = ["a","b","1","2", ...]

a alone, then twelve bs β†’ b followed by digits '1', '2'.

Constraints

  • 1 <= chars.length <= 2000
  • chars[i] is a lowercase/uppercase letter, digit, or symbol.
  • Must run in O(n) time and O(1) extra space β€” the in-place overwrite is the entire difficulty.

Think about it first

Hint 1 First solve it with a separate output list: scan runs, append char + count. The in-place version is the same scan β€” the only question is where to put the output.
Hint 2 Use a `read` pointer to find the end of each run and a `write` pointer for the compressed output. Why is it guaranteed that `write` never overtakes `read`?
Hint 3 Because a run of length L (L β‰₯ 2) compresses to at most 1 + digits(L) ≀ L characters, the compressed prefix never outgrows the consumed input. Scan run by run: write the char, and if the run length is > 1, write each digit of the length with `str(length)`.
Your workspace Not runnable by design β€” this is your interview scratchpad. Saved on this device.