Count and Say
Solution 1
对于一种非常经典的压缩算法的模拟,思路也比较直接,重点是如何进行优化。整体的思路就是基于前一个字符串进行遍历,通过状态量构造一个只包含连续相同字符的滑动窗口,并记录对应地字符和数字。由于这一递归造成的复杂度增长是指数规模的,因此本题的优化很重要。官方给出的尾递归方案就是一个非常好的优化递归函数空间占用的方案。此外本题还可以进一步优化字符串的相关处理,介于本人对C++的了解,选了一个浅显的方案(是的我学的不咋地……)
- 时间复杂度: O ( 2 n ) O(2^n) O(2n),按照最坏情况考虑,每一次递归串长度增大一倍,因此有 O ( ∑ i = 0 n − 1 2 i ) = O ( 2 n ) O(\sum_{i=0}^{n - 1}2^i) = O(2^n) O(∑i=0n−12i)=O(2n)
- 空间复杂度: O ( 2 n − 1 ) O(2^{n - 1}) O(2n−1),第N次处理的长度是 2 N − 1 2^{N - 1} 2N−1的
class Solution {
public:
string countAndSay(int n) {
return this->compressor(n, "1");
}
private:
string compressor(int n, string input) {
if (n == 1) {
return input;
}
vector<char> tmp;
int pos = 0, count = 0;
char cur = input[0];
while (pos < input.size()) {
if (input[pos] == cur) {
pos++;
count++;
}
else {
tmp.push_back(char(count + 48));
tmp.push_back(cur);
count = 0;
cur = input[pos];
}
}
tmp.push_back(char(count + 48));
tmp.push_back(cur);
string output;
// for (auto item: tmp) {
// output += item;
// }
output.insert(output.begin(), tmp.begin(), tmp.end());
return compressor(n - 1, output);
}
};
Solution 2
Solution 1的Python实现
class Solution:
def countAndSay(self, n: int) -> str:
return self.__compressor(n, "1")
def __compressor(self, n: int, inputs: str) -> str:
if n == 1: return inputs
tmp = list()
pos, count, cur = 0, 0, inputs[0]
while pos < len(inputs):
if inputs[pos] == cur:
pos += 1
count += 1
else:
tmp.append(str(count))
tmp.append(cur)
count = 0
cur = inputs[pos]
tmp.append(str(count))
tmp.append(cur)
outputs = "".join(tmp)
return self.__compressor(n - 1, outputs)