The problem asks us to compress a list of characters in-place and return the new length. Since we need to modify the array while reading it, a Two Pointer approach is perfect. One pointer (read_index) reads through the original characters to find groups, and another pointer (write_index) keeps track of where we are writing the compressed result.
Approach
- Initialize two pointers:
read_index: used to iterate through the array and counting consecutive characters.write_index: used to overwritecharswith our compressed results.
- Iterate through the array
while read_index < len(chars). - Inside the loop, we identify the current character (
ch) and count its consecutive occurrences using an innerwhileloop. - Once we have the count:
- We write the character
chto thewrite_indexposition. - If the count is greater than 1, we convert the count to a string and write each digit to the
charsarray, incrementingwrite_indexas we go.
- We write the character
- Finally, we return
write_index, which represents the new length of the compressed array.
Example Trace: Chars = ["a", "a", "B", "B", "C"]
- Start Pointers read_index (
R) and write_index (W) start at the beginning.
["a", "a", "b", "b", "c"]
^ ^
W R
- Process Group
a. We find twoas. We writeaand2.
["a", "2", "b", "b", "c"]
^ ^
W R
- Process Group
bWe find twobs. We writeband2.
["a", "2", "b", "2", "c"]
^ ^
W R
- Process Group
cWe find onec. We writec. (no number needed)
["a", "2", "b", "2", "c"]
^ (Done)
W
Code
def compress(self, chars: List[str]) -> int:
if not chars:
return 0
write_index = 0
read_index = 0
N = len(chars)
while read_index < N:
current_char = chars[read_index]
count = 0
while read_index < N and chars[read_index] == current_char:
count += 1
read_index += 1
chars[write_index] = current_char
write_index += 1
if count > 1:
for digit in str(count):
chars[write_index] = digit
write_index += 1
return write_index
Complexity
Time complexity: $O(N)$
We iterate through thecharsarray exactly once.Space complexity: $O(1)$
We perform the compression in-place.