题目:给出第n个count_and_say序列
1. 1
2. 11
3. 21
4. 1211
5. 111221
6. 312211
7. 13112221
8. 1113213211
9. 31131211131221
10. 13211311123113112211
方法1:复杂度 是O(n*m) ,m是第n步时字符串的长度,属于暴力破解,很直接的方法
https://leetcode.com/problems/count-and-say/discuss/16354/C%2B%2B-solution-runtime-O(n)-space-O(n)
class Solution {
public:
std::string countAndSay(int n) {
if (0 == n) return "";
if (1 == n) return "1";
std::string res="1";
std::string s;
for (int i = 1; i < n; i++){ // run from starting to generate second string
int len = res.size();
//cheack all digits in the string
for (int j = 0; j < len; j++){
int count=1; // we have at least 1 occourence of each digit
// get the number of times same digit occurred (be carefull with the end of the string)
while ((j + 1 < len) && (res[j] == res[j + 1])){
count++;
j++; // we need to keep increasing the index inside of the string
}
// add to new string "count"+"digit itself"
s += std::to_string(count) + res[j];
}
// save temporary result
res = s;
// clean our string-helper
s.clear();
}
return res;
}
};
方法2:与方法1基本相同
class Solution {
public:
string countAndSay(int n) {
if(0 == n) return "";
string res = "1";
while(--n){
string cur = "";
for(int i = 0; i <res.size();i++){
int count = 1;
while((i+1<res.size())&&(res[i]==res[i+1])){
count++;
i+=1;
}
cur += to_string(count)+res[i];
}
res = cur;
}
return res;
}
};
方法3:递归,没明白其中的思路
string countAndSay(int n){
if(1 == n) return "1";
if(2 == n) return "11";
string result = countAndSay(n - 1);
string newresult = "";
int count = 1;
for(int i = 1;i < result.size(); ++i){
if(result[i] != result[i-1]){
//https://leetcode.com/problems/count-and-say/discuss/16113/How-to-proof-the-COUNT-is-always-less-than-10
newresult.push_back('0'+count);//需要证明count < 10,这一点需要证明的,上一行链接
newresult.push_back(result[i-1]);
count = 1;
}else{
count++;
}
if(i == result.size() - 1){
newresult.push_back('0'+back);
newresult.push_back(result[i]);
}
}
result newresult;
}
方法4:python groupby,非常高超的手法,学不来
def countAndSay(n):
result = "1"
for _ in range(n - 1):
# original
# s = ''.join(str(len(list(group))) + digit for digit, group in itertools.groupby(s))
# decomposed
v = '' # accumulator string
# iterate the characters (digits) grouped by digit
for digit, group in itertools.groupby(result):
count = len(list(group)) # eg. the 2 in two 1s
v += "%i%s" % (count, digit) # create the 21 string and accumulate it
result = v # save to result for the next for loop pass
# return the accumulated string
return result
方法5:正则表达式
def countAndSay(self, n):
s = '1'
for _ in range(n - 1):
s = re.sub(r'(.)\1*', lambda m: str(len(m.group(0))) + m.group(1), s)
return s
def countAndSay(self, n):
s = '1'
for _ in range(n - 1):
s = ''.join(str(len(group)) + digit
for group, digit in re.findall(r'((.)\2*)', s))
return s