StringCompression [source code]

public class StringCompression {
static
/******************************************************************************/
class Solution {
    public int compress(char[] chars) {
        assert chars.length > 0;
        int pStart = 0, pEnd = 0, pStore = 0;
        while (pEnd < chars.length) {
            // Move pEND to the first position where the current letter (at pSTART) is finished
            while (pEnd < chars.length && chars[pEnd] == chars[pStart])
                pEnd++;
            int len = pEnd - pStart;
            // Store this run's letter
            chars[pStore++] = chars[pStart];
            if (len > 1) {
                // this can't be done if len == 1: will possibly overwrite [pEND], which is not processed yet
                char[] chsLen = Integer.toString (len).toCharArray ();
                // Store the length of this run, digit by digit
                for (char c : chsLen)
                    chars[pStore++] = c;
            }
            // bring pSTART to speed with pEND: the next run of same letters to process
            pStart = pEnd;
        }
        return pStore;
    }
}
/******************************************************************************/

    public static void main(String[] args) {
        StringCompression.Solution tester = new StringCompression.Solution();
    }
}

downvote出奇的多的一个题目, 还没有看出来复杂度在哪里, 准备直接就开始乱写了; 当然这个题目的笨办法就很简单, 直接counts就行了; 但是Follow-Up你准备怎么处理呢? 一个可能的方向是直接在input里面记录counts? 不对, 好像可以用快慢指针的方式来实现;

思路大概是有的, 从一个concrete的例子出发, 开始写算法, 我用的是abbcccaaabbbccc;

写的时候感觉小细节很多的一个算法, 结果写完之后一次AC了, 速度是8ms (41%), 可以接受;

这个题目还是有不少值得学习的地方的, 尤其是三个指针版本的快慢指针算法, 以前其实是没有专门写过的; 不过其实三指针版本本身还是很intuitive的; 另外, 还是强调笔算的重要性, 如果不是自己动笔, 我是没有办法意识到这里两个指针不够的;


editorial里面awice的解法: 10(12)

class Solution {  
    public int compress(char[] chars) {  
        int anchor = 0, write = 0;  
        for (int read = 0; read < chars.length; read++) {  
            if (read + 1 == chars.length || chars[read + 1] != chars[read]) {  
                chars[write++] = chars[anchor];  
                if (read > anchor) {  
                    for (char c: ("" + (read - anchor + 1)).toCharArray()) {  
                        chars[write++] = c;  
                    }  
                }  
                anchor = read + 1;  
            }  
        }  
        return write;  
    }  
}

写法上看起来比我的好看, 因为没有两重循环; 但是实际上是类似的; 他的这个算法本质上还是依赖于类似分段算法里面的switch; 我因为不想处理收尾, 所以避免了这个算法;

具体的细节懒得看了, 大概意思应该是知道的; 注意他这里判断的read > anchor跟我的len > 1其实是类似的, 因为他这里read记录的其实是一个run最后的一个letter的位置, 而不是下一个run的开头, 所以他这里可以直接用一个>就可以判断了;


discussion基本没有其他什么新奇的解法;


submission的最优解大部分也就都是波动而已;


Problem Description

Given an array of characters, compress it in-place.

The length after compression must always be smaller than or equal to the original array.

Every element of the array should be a character (not int) of length 1.

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

Follow up:
Could you solve it using only O(1) extra space?

Example 1:

Input:  
["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:  
"aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3".

Example 2:

Input:  
["a"]  

Output:  
Return 1, and the first 1 characters of the input array should be: ["a"]  

Explanation:  
Nothing is replaced.

Example 3:

Input:  
["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:  
Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12".  
Notice each digit has it's own entry in the array.

Note:

  • All characters have an ASCII value in [35, 126].
  • 1 <= len(chars) <= 1000.

Difficulty:Easy
Total Accepted:8.6K
Total Submissions:23.4K
Contributor:Grain_In_Ear
Companies
microsoftbloombergsnapchatyelpexpediagodaddylyft
Related Topics
string
Similar Questions
Count and SayEncode and Decode StringsDesign Compressed String Iterator

Hint 1
How do you know if you are at the end of a consecutive group of characters?

results matching ""

    No results matching ""