原题目
面试题 01.06. 字符串压缩
字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa
会变为a2b1c5a3
。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。
示例1:
输入:"aabcccccaaa"
输出:"a2b1c5a3"
示例2:
输入:"abbccd"
输出:"abbccd"
解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。
提示:
- 字符串长度在[0, 50000]范围内。
第一遍解法
双指针,
若 S 不是空串,则压缩后的字符串长度至少为2,所以S.size() < 2时,"压缩"后的字符串不会变短,所以直接返回S。
i 指向相同字符串的第一个索引,通过遍历使得 j 指向与前字符第一次不相同的位置。 j - i 为字符出现的次数。
代码如下:
class Solution {
public:
string compressString(string S) {
if (S.size() < 2) { return S; }
string res = "";
int i = 0, j = 1;
while (i < S.size()) {
while (j < S.size() && S[i] == S[j]) {
j++;
}
res += S[i];
res += to_string(j-i);
i = j;
j = i + 1;
}
return res.size() < S.size() ? res : S;
}
};
时间复杂度: O(n)
空间复杂度: O(n)
网上好的解法
也是双指针,思路与第一次解法一致,链接中作者画了示意图,更容易理解。
string compressString(string S) {
int N = S.length();
string res;
int i = 0;
while (i < N) {
int j = i;
while (j < N && S[j] == S[i]) {
j++;
}
res += S[i];
res += to_string(j - i);
i = j;
}
if (res.length() < S.length()) {
return res;
} else {
return S;
}
}
作者:nettee
链接:https://leetcode-cn.com/problems/compress-string-lcci/solution/shuang-zhi-zhen-fa-qu-lian-xu-zi-fu-cpython-by-net/
来源:力扣(LeetCode)
时间复杂度: O(n)
空间复杂度: O(n)
最后的代码
双指针,优化了自己的第一次解法。
class Solution {
public:
string compressString(string S) {
if (S.size() < 2) { return S; }
string res = "";
int i = 0;
while (i < S.size()) {
int j = i + 1; // 相比int j = i,每次“压缩”都少比较了一次。
while (j < S.size() && S[i] == S[j]) {
j++;
}
res += S[i];
res += to_string(j - i);
i = j;
}
return res.size() < S.size() ? res : S;
}
};
小结
- to_string方法可以将数字转换为相应的字符串。