String Compression

Problem statement

You get a character array that may contain consecutive runs of the same character. Compress it in place with run-length style groups: one copy of the character, then the decimal digits of the run length when the run is longer than 1. Return the new logical length of the compressed array (the first that many slots of chars hold the answer).

Example:

Input:

chars = ["a","a","b","b","c","c","c"]

Expected output:

length 6, chars begins ["a","2","b","2","c","3", ...]

Practice on LeetCode: String Compression

Golang Solution

Advance a read pointer over each run to count it, then write the character (and optional count digits) through a write pointer. Counts greater than 9 expand to multiple digit characters via strconv.Itoa.

Time: O(n)
Space: O(1) extra beyond a tiny digit buffer for each count

func compress(chars []byte) int {
    write := 0
    read := 0

    for read < len(chars) {
        current := chars[read]
        count := 0

        // Count consecutive occurrences.
        for read < len(chars) && chars[read] == current {
            read++
            count++
        }

        // Write the character.
        chars[write] = current
        write++

        // Write count only if > 1.
        if count > 1 {
            countBytes := []byte(strconv.Itoa(count))

            for _, b := range countBytes {
                chars[write] = b
                write++
            }
        }
    }

    return write
}