胖虎算法初练六之——外观数列

外观数列

给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。

注意:整数序列中的每一项将表示为一个字符串。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221

读懂题:


第一项是数字 1

2 描述前一项,这个数是 1中的数为"11",即 “一个 1 ”,记作 11

3 描述前一项,这个数是 2中的数为"11", 即 “两个 1 ” ,记作 21

4 描述前一项,这个数是 3中的数为"21", 即 “一个 2 一个 1 ” ,记作 12 11

5 描述前一项,这个数是 4中的数为"1211",即 “一个 1 一个 2 两个 1 ” ,记作 11 12 21

6 描述前一项,这个数是 5中的数为"111221",即 “三个 1 两个 2 一个 1 ” ,记作 31 22 11

7 描述前一项,这个数是 6中的数为"312211",即“一个3 一个1 两个2 两个1”,记做13112221

方法一(StringBuilder + 双指针 )

  • 使用指针 i 和 指针 j 来对需要描述的字符 str 进行遍历,指针 i 指向 指针 j 的下一个位置,即 i = j + 1;

  • 若 str.charAt(i) == str.charAt(j)时,指针 i 继续移动

  • 若 str.charAt(i) != str.charAt(j)时,将相等元素的个数及值放入StringBuilder中,即      stringBuilder.append(i-j).append(str.charAt(j)).   i-j为str.charAt(j)的个数,并且并且指针 j 进行跳转,j = i

  • 退出内循环后,字符串中的最后元素还没有描述。利用stringBuilder.append(i-j).append(str.charAt(j)) 进行描述。 此时i的值与str.length()相同。

  • 最后将StringBuilder中的值传入到str中,并且清空stringBuilder用于接收下个循环中新提添加的字符数组。

代码如下

class Solution {
    public  String countAndSay(int n) {
        // 只需要知道前一个就可以进行描述 - 要得到n项, 只需要知道n-1项
        String str = "1"; // 存储前一项所描述的信息
        StringBuilder stringBuilder = new StringBuilder();
        int i, j ;
        for(int k = 1; k < n; k++){ //循环遍历从1到(n-1)
            for(j=0,i=j+1; i < str.length(); i++){
                if (str.charAt(i) != str.charAt(j)){
                    // 进行添加
                    stringBuilder.append(i - j).append(str.charAt(j));
                    j = i;
                } 
            }
            // 处理只有一个元素和最后一个元素
            stringBuilder.append(i - j).append(str.charAt(j));//此时i的值与str.length()相                
                                                            // 同,j为上边循环完时候的j值。
            str = stringBuilder.toString();//将字符数组转换为字符串
            stringBuilder.delete(0, stringBuilder.length());//每次都清空,等待添加新的字符数组。
        }  
        return str;
    }
}

方法二(利用递归)

因为只需要知道前一个就可以进行描述。 要得到n项, 只需要知道n-1项,所以也可以使用递归来进行求解。结束条件为 n = 1时,返回 "1"。

class Solution {
    StringBuilder stringBuilder = new StringBuilder();
    public  String countAndSay(int n) {
        if(n==1){
            return "1";
        }
        int i, j ;
        String str=countAndSay(n-1);
        for(j=0,i=j+1; i < str.length(); i++){
            if (str.charAt(i) != str.charAt(j)){
                // 进行添加
                stringBuilder.append(i - j).append(str.charAt(j));
                j = i;
            } 
        }
    // 处理只有一个元素和最后一个元素
    stringBuilder.append(i - j).append(str.charAt(j));//此时i的值与str.length()相同,j为                                                                上边循环完时候的j值。
    str = stringBuilder.toString();//将字符数组转换为字符串
    stringBuilder.delete(0, stringBuilder.length());//每次都清空,等待添加新的字符数组。  
    return str;
    }   
}

代码实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值