leetcode题解(C++版)

leetcode-443-Median of Two Sorte

2018-09-03  本文已影响0人  去年匆匆今年匆匆

443. String Compression

题目:

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?

Example1:

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".

Example2:

Input:
["a"]

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

Explanation:
Nothing is replaced.

Example3:

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.

解法一

解析

        还是用一个新的数组,先把答案存起来,最后交换chars。

代码(C++)

class Solution {
public:
    int compress(vector<char>& chars) {
        if(chars.size() == 0) return 0;
        vector<char> v;
        v.push_back(chars[0]);
        int sum = 1;
        for(int i = 1;i < chars.size(); i ++){
            if(chars[i-1] == chars[i]&&i != chars.size()-1) sum++;
            else {
                if(chars[i-1] == chars[i]&&i == chars.size()-1) {
                    f(v, sum+1);
                    break;
                }
                if(sum != 1) f(v, sum);
                v.push_back(chars[i]);
                sum = 1;
            }
        }
        swap(v, chars);
        return chars.size();
    }
    void f(vector<char>& v, int n){
        string s = to_string(n);
        for(int i = 0; i < s.length(); i ++)
            v.push_back(s[i]);
    }
};

解法二

解析

实现O(1)的空间复杂度,需要建一个索引cur,直接修改原串,记录压缩后的字符串。遍历字符串,逐个找字符连续出现的范围。先将该字符拷贝到原串的cur上,如果该字符出现一次,不再操作,如果多次,则将该字符的次数追加到cur之后,修改cur。

例如:["a","b","b","c","c","c"]

开始cur = 0,“a”出现一次,无需压缩。chars[cur++] = chars[0]即可。接着"b"出现2次,则有chars[cur++] = chars[1], chars[cur++] = chars[2]。原串中chars[2]变为"2",cur = 3,类似地,有chars[cur++] = chars[3], chars[cur++] = chars[4]。chars[4]变为"3",此时cur = 5,即为压缩后的字符串长度。原串压缩为["a","b","2","c","3"]。

这种压缩方式,字符连续出现频率高,才能有较好的压缩效果。

代码(C++)

class Solution {
public:
    int compress(vector<char>& chars) {
        int n = chars.size();
        int cur = 0; // 记录当前字符的索引,最后为压缩字符串的长度
        for(int i = 0; i < n; ) {
            int j = i;
            while( j < n - 1 && chars[j] == chars[j+1]) {// 查找字符连续相同的个数
                j++;
            }
            chars[cur++] = chars[i];// 将当前字符写入原字符串中
            if(i != j) {
                string times = to_string(j - i + 1);// 字符连续相同的个数
                int tLen = times.length();
                for(int k = 0; k < tLen; k++) {//把字符连续相同个数写入字符串,用来压缩
                    chars[cur++] = times[k];
                }
            }
            i = j + 1;//接着处理下一个字符
        }
        return cur;
    }
};  

代码(python)

class Solution(object):
    def compress(self, chars):
        """
        :type chars: List[str]
        :rtype: int
        """
        n = len(chars) 
        cur = 0 # 当前字符的索引,用以压缩原字符串
        i = 0
        while i < n:
            j = i
            while j < n - 1 and chars[j] == chars[j+1]:# 找字符连续出现的次数
                j += 1
            chars[cur] = chars[i] # 记录当前处理的字符
            cur += 1
            if i != j:
                times = str(j-i+1) # 将字符的次数写入原串中
                tLen = len(times)
                for k in range(tLen):
                    chars[cur+k] = times[k]
                cur += tLen
            i = j + 1 # 处理下一个字符
        return cur
上一篇下一篇

猜你喜欢

热点阅读