Published on

String compression

Authors
  • avatar
    Name
    Khánh
    Twitter

String Compression

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

Begin with an empty string s. For each group of consecutive repeating characters in chars:

If the group's length is 1, append the character to s. Otherwise, append the character followed by the group's length. The compressed string s should not be returned separately, but instead, be stored in the input character array chars. Note that group > lengths that are 10 or longer will be split into multiple characters in chars.

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

You must write an algorithm that uses only constant extra space.

Example 1:

Input: chars = ["a","a","b","b","c","c","c"]
Output: Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"]
Explanation: The groups are "aa", "bb", and "ccc". This compresses to "a2b2c3".

Example 2:

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

Example 3:

Input: chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
Output: Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"].
Explanation: The groups are "a" and "bbbbbbbbbbbb". This compresses to "ab12".

My Solutions

To resolve this solutions, we need to discover a requirements factors like:

  • Modify the input array
  • Do not modify the rest of the input array
  • Do not use nested loop (easy solution but not effectively)
  • Notice a case is streaks greater than 9

Steps:

  • Using While to loop through the s[]
  • Using modifyIndex like the pointer which means the location we can fill the result of streaks.
  • If a character same with a character before -> Count up streaks
  • Else handle update previous characters streaks and update modifyIndex - notice that the streaks value greater than 9 (there are two character)
const solutions = (s: string[]) => {
  let i = 1;
  let modifyIndex = 0;
  let streaks = 1;
  let compressCount = 0;

  while (i < s.length) {
    if (s[i] === s[i - 1] && i !== s.length - 1) {
      // count streaks
      chuoi += 1;
      i++;
    } else {
      // for the character in the end of string[]
      if (s[i] === s[i - 1]) {
        chuoi += 1;
      }

      // write down the previous streaks
      s[modifyIndex] = s[i - 1];
      modifyIndex++;

      if (chuoi > 1) {
        // count total compress value
        compressCount += chuoi;
        const str = String(chuoi).split("");
        str.forEach((c) => {
          s[modifyIndex] = c;
          modifyIndex += 1;
        });
      }

      // reset streaks
      chuoi = 1;

      i++;
    }
  }
  return compressCount;
};

solutions(['a', 'a', 'b', 'c', 'c','c', 'c', 'c', 'c', 'c','c', 'c', 'c', 'c', 'c','a', 'a', 'd', 'd']) 
// ['a', '2', 'b', 'c', '1','2', 'a', '2', 'd', '2','c', 'c', 'c', 'c', 'c','a', 'a', 'd', 'd']
// 18