Leetcode --- NO.38 外观数列(Java)

题目描述

在这里插入图片描述
在这里插入图片描述

题目分析

  • 简单来说,就是分析之前要生成相对应的字符串,然后再做统计,继续生成字符串,显而易见,需要用到递归

解法分析

  • 整个步骤有两步,第一步生成上一层的字符串,第二步统计上一层字符串
  • 生成可以使用递归逐级生成
  • 统计需要遍历,大致的步骤为,判断下一个是否与前一个相等,如果相等就继续看下一个,不等就将字符个数和字符放到结果字符串中,也就是使用双指针法
  • 这里推荐使用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();
    }
}

猜你喜欢

转载自blog.csdn.net/Kobe_k/article/details/107401856