跳转至

3163. 压缩字符串 III

题目描述

给你一个字符串 word,请你使用以下算法进行压缩:

  • 从空字符串 comp 开始。当 word 不为空 时,执行以下操作:
    • 移除 word 的最长单字符前缀,该前缀由单一字符 c 重复多次组成,且该前缀长度 最多 为 9 。
    • 将前缀的长度和字符 c 追加到 comp

返回字符串 comp

 

 

示例 1:

输入:word = "abcde"

输出:"1a1b1c1d1e"

解释:

初始时,comp = "" 。进行 5 次操作,每次操作分别选择 "a""b""c""d""e" 作为前缀。

对每个前缀,将 "1" 和对应的字符追加到 comp

示例 2:

输入:word = "aaaaaaaaaaaaaabb"

输出:"9a5a2b"

解释:

初始时,comp = ""。进行 3 次操作,每次操作分别选择 "aaaaaaaaa""aaaaa""bb" 作为前缀。

  • 对于前缀 "aaaaaaaaa",将 "9""a" 追加到 comp
  • 对于前缀 "aaaaa",将 "5""a" 追加到 comp
  • 对于前缀 "bb",将 "2""b" 追加到 comp

 

提示:

  • 1 <= word.length <= 2 * 105
  • word 仅由小写英文字母组成。

解法

方法一:双指针

我们可以利用双指针,统计每个字符的连续出现次数。假如当前字符 $c$ 连续出现了 $k$ 次,然后我们将 $k$ 划分成若干个 $x$,每个 $x$ 最大为 $9$,然后将 $x$ 和 $c$ 拼接起来,将每个 $x$ 和 $c$ 拼接起来到结果中。

最后返回结果即可。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 word 的长度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution:
    def compressedString(self, word: str) -> str:
        g = groupby(word)
        ans = []
        for c, v in g:
            k = len(list(v))
            while k:
                x = min(9, k)
                ans.append(str(x) + c)
                k -= x
        return "".join(ans)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
    public String compressedString(String word) {
        StringBuilder ans = new StringBuilder();
        int n = word.length();
        for (int i = 0; i < n;) {
            int j = i + 1;
            while (j < n && word.charAt(j) == word.charAt(i)) {
                ++j;
            }
            int k = j - i;
            while (k > 0) {
                int x = Math.min(9, k);
                ans.append(x).append(word.charAt(i));
                k -= x;
            }
            i = j;
        }
        return ans.toString();
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
    string compressedString(string word) {
        string ans;
        int n = word.length();
        for (int i = 0; i < n;) {
            int j = i + 1;
            while (j < n && word[j] == word[i]) {
                ++j;
            }
            int k = j - i;
            while (k > 0) {
                int x = min(9, k);
                ans.push_back('0' + x);
                ans.push_back(word[i]);
                k -= x;
            }
            i = j;
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
func compressedString(word string) string {
    ans := []byte{}
    n := len(word)
    for i := 0; i < n; {
        j := i + 1
        for j < n && word[j] == word[i] {
            j++
        }
        k := j - i
        for k > 0 {
            x := min(9, k)
            ans = append(ans, byte('0'+x))
            ans = append(ans, word[i])
            k -= x
        }
        i = j
    }
    return string(ans)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function compressedString(word: string): string {
    const ans: string[] = [];
    const n = word.length;
    for (let i = 0; i < n; ) {
        let j = i + 1;
        while (j < n && word[j] === word[i]) {
            ++j;
        }
        let k = j - i;
        while (k) {
            const x = Math.min(k, 9);
            ans.push(x + word[i]);
            k -= x;
        }
        i = j;
    }
    return ans.join('');
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * @param {string} word
 * @return {string}
 */
var compressedString = function (word) {
    const ans = [];
    const n = word.length;
    for (let i = 0; i < n; ) {
        let j = i + 1;
        while (j < n && word[j] === word[i]) {
            ++j;
        }
        let k = j - i;
        while (k) {
            const x = Math.min(k, 9);
            ans.push(x + word[i]);
            k -= x;
        }
        i = j;
    }
    return ans.join('');
};

方法二:双指针

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function compressedString(word: string): string {
    let res = '';

    for (let i = 1, j = 0; i <= word.length; i++) {
        if (word[i] !== word[j] || i - j === 9) {
            res += i - j + word[j];
            j = i;
        }
    }

    return res;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function compressedString(word) {
    let res = '';

    for (let i = 1, j = 0; i <= word.length; i++) {
        if (word[i] !== word[j] || i - j === 9) {
            res += i - j + word[j];
            j = i;
        }
    }

    return res;
}

方法三:正则匹配

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function compressedString(word: string): string {
    const regex = /(.)\1{0,8}/g;
    let m: RegExpMatchArray | null = null;
    let res = '';

    while ((m = regex.exec(word))) {
        res += m[0].length + m[1];
    }

    return res;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function compressedString(word) {
    const regex = /(.)\1{0,8}/g;
    let m = null;
    let res = '';

    while ((m = regex.exec(word))) {
        res += m[0].length + m[1];
    }

    return res;
}

评论