leetcode之Count and Say报数

题目链接:Count and Say报数

一开始试图找规律,直接写了个简单粗暴的代码,跑起来好像没发现规律。

试着提交居然过了,但是速度比较慢,就改进了下代码。

按题意来的简单粗暴的代码(40ms)如下:

public String countAndSay(int n) {
    List<Integer> arr = new ArrayList<Integer>();
    List<Integer> res = new ArrayList<Integer>();
    arr.add(1); // 初始化数列
    for (int i = 2; i <= n; i++) {
        int count = 0, pre = -1;    // 用pre存储数列中arr(k)的前一个数
        for (int k = 0; k < arr.size(); k++) {
            // 判断前一个数是否与当前数相等,是则count+1
            // 否则将count与pre存入res,重置count,pre
            if (((Integer)arr.get(k)) != pre) {
                if (count > 0) {
                    res.add(count);
                    res.add(pre);
                }
                count = 1;
                pre = arr.get(k);
            } else count++;
        }
        res.add(count);
        res.add(pre);
        arr.clear();    // 将arr清空
        arr.addAll(res);    // 将res数列复制到arr中
        res.clear();    // 将res清空
    }
    StringBuilder ans = new StringBuilder();
    // 遍历数列已返回结果
    for (Integer a : arr) ans.append(a);
    return ans.toString();
}

之后做了一些改进(5ms),这样的改进,测试数据组数越多,效果越明显

public class CountAndSay {
/*改进:
 * 1.第一次提交后发现n貌似不是特别大
 *   n范围好像是1--57
 *   所以可以使用一个List<StringBuilder>来
 *   存我们求n时计算的n-1,n-2,....,3,2,1避免了一些重复计算
 * 2.直接使用StringBuilder,
 *   比List<Integer>转String减少了个循环,
 * 3.至于为何不直接用String,
 *   这样StringBuilder到toString都免了,
 *   请自行百度StringBuilder与String顺带个StringBuffer
 * */
private static List<StringBuilder> list = new ArrayList<StringBuilder>(60);

static {
    list.add(new StringBuilder("1"));
}

public String countAndSay(int n) {
    if (list.size() > n - 1) {
        if (n - 1 < 0) return null;
        return ((StringBuilder)list.get(n - 1)).toString();
    } else {
        
        StringBuilder arr = (StringBuilder)list.get(list.size() - 1);
        StringBuilder res = new StringBuilder();
        
        for (int i = list.size(); i < n; i++) {
            int count = 0;
            char pre = 0;
            
            for (int k = 0; k < arr.length(); k++) {
                if (arr.charAt(k) != pre) {
                    if (count > 0) res.append(count).append(pre);
                    count = 1;
                    pre = arr.charAt(k);
                } else count++;
            }
            res.append(count).append(pre);
            
            arr = res;
            res = new StringBuilder(); 
            
            list.add(arr);
        }
        return arr.toString();
    }
}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值