String Compression

problem [https://leetcode.com/problems/string-compression/ 443. String Compression].

Problem description
Given an array of characters, compress it using the following algorithm:

Begin with an empty string. For each group of consecutive repeating characters in :
 * If the group's length is 1, append the character to.
 * Otherwise, append the character followed by the group's length.

The compressed string  should not be returned separately, but instead be stored in the input character array  . Note that group lengths that are 10 or longer will be split into multiple characters in.

After you are done modifying the input array, return the new length of the array.


 * Follow up
 * Could you solve it using only  extra space?


 * Example 1
 * Input:
 * Output: Return 6, and the first 6 characters of the input array should be:.
 * Explanation: The groups are " ", " ", and " ". This compresses to " ".


 * Example 2
 * Input:
 * Output: Return 1, and the first character of the input array should be:.
 * Explanation: The only group is " ", which remains uncompressed since it's a single character.


 * Example 3
 * Input:
 * Output: Return 4, and the first 4 characters of the input array should be:.
 * Explanation: The groups are " " and " ". This compresses to " ".


 * Example 4
 * Input:
 * Output: Return 6, and the first 6 characters of the input array should be:.
 * Explanation: The groups are " ", " ", and " ". This compresses to " ". Note that each group is independent even if two groups have the same character.


 * Constraints
 * is a lower-case English letter, upper-case English letter, digit, or symbol.
 * is a lower-case English letter, upper-case English letter, digit, or symbol.

Corner case
If the input array's length is 0 or 1, then we just return the length, and do nothing on the array.

General approach
There are some important properties we would notice as we modify the input character array in-place:
 * 1) Repeat counts of 1 are not stored in the output.
 * 2) The number characters taken to store a letter followed repeat counts in the output is less than or equal to the number of characters in the original segment of repetition.
 * 3) * 2-9: one original character + one digit.
 * 4) * 10-99: one original character + two digits.
 * 5) * 100-999: one original character + three digits.
 * 6) Modifying the input array in-place never expands it.
 * 1) Modifying the input array in-place never expands it.

So we can use three pointers as follows:
 * 1)   pointer: to mark the beginning of a segment of repeated characters.
 * 2)   pointer: to move forward to find the next different character / end of input.
 * 3)   pointer: to mark the tail of generated compressed string, and to return the length of compressed string at the end.

We start the loop by setting,  , and.

Then we move forward the fast pointer until it passes the end.

In each single iteration we do the following:
 * If  has not reached one-past-end, and , then we just move forward   without changing the input array.
 * If  has reached one-past-end, or if , then we need to do the compression:
 * Copy  to.
 * Move forward.
 * If, then put each digit of   into  , starting from   position. Move   forward, one past the last digit.
 * Set.
 * Move forward  by one position.
 * Move forward  by one position.

Repeat until  reaches two-past-end, i.e. the entire string is compressed.

Illustration

 * Color notations on Input row
 * lime or cyan &mdash; characters that have been processed, and become part of output.
 * silver &mdash; characters that have been processed, and do not become part of output.
 * uncolored &mdash; characters yet to be processed.


 * Input :
 * {| style="min-width: 600px; text-align: center;"

! Index || 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 ! Input || a || b || b || c || c || c || c || c || c || c || c || c || c || c || d || e || e ! ! !
 * 0
 * || 1
 * 0
 * }


 * After processing
 * {| style="min-width: 600px; text-align: center;"

! Index || 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || || ! Input ! style="background-color: lime;" | a ! b || b || c || c || c || c || c || c || c || c || c || c || c || d || e || e ! ! !
 * || 1
 * || || 2
 * || 1
 * }


 * After processing
 * {| style="min-width: 600px; text-align: center;"

! Index || 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || || ! Input ! style="background-color: lime;" | a ! style="background-color: cyan;" | b ! style="background-color: cyan;" | 2 ! c || c || c || c || c || c || c || c || c || c || c || d || e || e ! ! !
 * || || || 3
 * || || || || 4
 * || || || 3
 * }


 * After processing
 * {| style="min-width: 600px; text-align: center;"

! Index || 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 ! Input ! style="background-color: lime;" | a ! style="background-color: cyan;" | b ! style="background-color: cyan;" | 2 ! style="background-color: lime;" | c ! style="background-color: lime;" | 1 ! style="background-color: lime;" | 1 ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! d || e || e ! ! !
 * || || || || || || || || || || || || || || 14
 * || || || || || || || || || || || || || || || 15
 * || || || || || || 6
 * }


 * After processing
 * {| style="min-width: 600px; text-align: center;"

! Index || 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 ! Input ! style="background-color: lime;" | a ! style="background-color: cyan;" | b ! style="background-color: cyan;" | 2 ! style="background-color: lime;" | c ! style="background-color: lime;" | 1 ! style="background-color: lime;" | 1 ! style="background-color: cyan;" | d ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | d ! e || e ! ! !
 * || || || || || || || || || || || || || || || 15
 * || || || || || || || || || || || || || || || || 16
 * || || || || || || || 7
 * }


 * After processing
 * {| style="min-width: 600px; text-align: center;"

! Index || 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 ! Input ! style="background-color: lime;" | a ! style="background-color: cyan;" | b ! style="background-color: cyan;" | 2 ! style="background-color: lime;" | c ! style="background-color: lime;" | 1 ! style="background-color: lime;" | 1 ! style="background-color: cyan;" | d ! style="background-color: lime;" | e ! style="background-color: lime;" | 2 ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | c ! style="background-color: silver;" | d ! style="background-color: silver;" | e ! style="background-color: silver;" | e ! ! !
 * || || || || || || || || || || || || || || || || || 17
 * || || || || || || || || || || || || || || || || || || 18
 * || || || || || || || || || 9
 * }


 * Output
 * Return value: 9
 * Compressed array:

Complexity analysis

 * Time complexity
 * Since we processed the entire string in one-pass, character by character, and for each character we have constant amount of computation, the time complexity is O(n)


 * Space complexity
 * Since we only used three pointers to complete the traversal and used no additional data structures, the space complexity is O(1).