题目描述
题目分析
- 简单来说,就是分析之前要生成相对应的字符串,然后再做统计,继续生成字符串,显而易见,需要用到递归
解法分析
- 整个步骤有两步,第一步生成上一层的字符串,第二步统计上一层字符串
- 生成可以使用递归逐级生成
- 统计需要遍历,大致的步骤为,判断下一个是否与前一个相等,如果相等就继续看下一个,不等就将字符个数和字符放到结果字符串中,也就是使用
双指针法
- 这里推荐使用
StringBuffer
而不要直接使用字符串拼接,可以提高效率,参看《String、StringBuffer和StringBuilder的区别》
代码
class Solution {
public String countAndSay(int n) {
if(n==1) return "1";
StringBuffer res = new StringBuffer();
String str = countAndSay(n-1);
// 开始计算的位置
int count = 0;
int len = str.length();
for(int i=1; i<len+1; i++){
// 如果是最后一个
if ( i == len){
// 两个指针的索引差就是相同字符的个数
return res.append(i - count).append(str.charAt(count)).toString();
}
// 如果当前指向的字符与开始计算区段开头的字符不同
if (str.charAt(i) != str.charAt(count)) {
res.append(i-count).append(str.charAt(count));
// 结算位置调至当前位置
count = i;
}
}
return res.toString();
}
}
- 还有另外一种方法,直接挨个遍历计数
class Solution {
public String countAndSay(int n) {
if(n==1) return "1";
if(n==2) return "11";
StringBuilder res= new StringBuilder();
String previous = countAndSay(n-1);
// 至少有一个字符
int count=1;
for(int i=0;i<previous.length()-1;i++){
// 如果后一个跟当前相同,就前进并计数
if(previous.charAt(i)==previous.charAt(i+1)){
count++;
}else{
// 如果不相同就放到结果字符串中,计数器重置
res.append(count).append(previous.charAt(i));
count=1;
}
}
// 如果到最后一个也是相同的,那么就不会走到else里的代码。
res.append(count).append(previous.charAt(previous.length()-1));
return res.toString();
}
}