【LeetCode38】【Count and Say】StringBuilder

1. 题目原文

The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, …

1 is read off as “one 1” or 11.
11 is read off as “two 1s” or 21.
21 is read off as “one 2, then one 1” or 1211.
Given an integer n, generate the nth sequence.

Note: The sequence of integers will be represented as a string.

2.题目解读

这道题的题目可以说完完全全的把我给误导了,当初怎么想都不对,最后在discussion里才知道了题目是让我们做什么:

我认为比较好的示例应该是这样的:
<1 1(经测试,是可以通过的)
1 1
2 11(1个1)
3 21(2个1)
4 1211(1个2,1个1)
5 111221(1个1,1个2,2个1)
6 312211(3个1,2个2,1个1)
7 13112221(以此类推)
8 1113213211
9 31131211131221
10 13211311123113112211
数字不断递增,则输出的字符串按照“下一个数字对应的数是上一个数字对应的数读出来的形式”的规律。

3. java代码

(1)普通迭代方法:

public String countAndSay1(int n) {
        if(n<=1){
            return "1";
        }else{
            StringBuilder curr = new StringBuilder("1");
            String pre = "1";
            char c = '1';   
            for(int i=2;i<=n;i++){              
                pre = curr.toString();
                c = pre.charAt(0);
                curr = new StringBuilder();
                int count = 0;
                for(int j=0;j<pre.length();j++){                    
                    if(pre.charAt(j)!=c){
                        curr.append(count).append(c);
                        c = pre.charAt(j);
                        count = 1;                      
                    }else{count++;}
                }
                curr.append(count).append(c);               
            }
            return curr.toString();
        }
    }

(2)递归实现方法:

    //递归实现
    public String countAndSay2(int n){
        if(n<=1){return "1";}
        String s = countAndSay2(n-1);
        StringBuilder sb = new StringBuilder();
        char c = s.charAt(0);
        int count = 0;
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)!=c){
                sb.append(count).append(c);
                c = s.charAt(i);
                count = 1;
            }else{count++;}
        }
        sb.append(count).append(c);     
        return sb.toString();
    }

(3)dfs方法:
dfs实现部分参考博文:http://www.cnblogs.com/huntfor/p/3849547.html

public class Solution {
    private String s = "1";

    public String countAndSay(int n){
        if(n<=1){return "1";}
        //控制循环次数n-1次
        for(int i=1;i<n;i++){
            dfs(s.length());
        }
        return s;
    }

    public void dfs(int length){
        if(length==0){return;}//停止标志
        int count = 1,i = 0;//count记录当前数字出现的个数
        while(i<length-1&&s.charAt(i)==s.charAt(i+1)){
            count++;
            i++;
        }               
        s = s.substring(i+1)+count+s.charAt(i);//截取掉已经记录了个数的数字,并且把个数和数字接到s后面
        dfs(length-count);//length-count为还需要循环截取记录长度的个数,直到其等于0时候返回新的s.
    }
}

4. 总结

(1)三种方法速度比较:
递归方法最快,且代码最为简介,但可能出现溢出问题。

对于leetcode测试用例,普通迭代比递归实现方法速度慢20%左右;dfs更慢,比前两者慢10倍左右,主要原因可能有三个:
(A)substring比较慢
(B)字符串拼接
(C)while判断条件比较复杂。
(2)StringBuilder简单用法

StringBuilder sb = new StringBuilder("1");//"1"为初始值,创建便存有这样的值
sb.append(1).append(2)//结果为:112
String s = sb.toString();//转换为字符串
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值