美文网首页
38. Count And Say 问题

38. Count And Say 问题

作者: MikeShine | 来源:发表于2019-12-20 11:48 被阅读0次

题目描述

这个 count&say 问题其实没什么难的。
简单说一下就是统计出现的频率。
“11122334” ==> “31222314”
就是说3个1,2个2,2个3,1个4。


自己的方法

从逻辑上来说就是向后遍历,然后比较和后面的元素是否一样,如果一样就 count++, 不一样就直接统计输出;最后一个元素需要特殊考虑一下

但是问题是,这里最终结果长度是不确定的,一开始想的是用 List<Character> 来存结果,但是这样来说最后是要有类型转换的。最后的类型转换就挺麻烦的。
涉及 List 转换到 Array,使用 List 中的 toArray() 方法,该方法的构造参数接收一个 array 的对象 。

List<String> list =  new ArrayList<>();
String res = list.toArray(new String[list.size()])
// list.toArray() 方法后面

代码

package String;

// 38. Count And Say 可以看到下面的例子,实际上就是在统计每一种出现的频率
//   整体来说这个逻辑是比较简单的,就是一些API不是很熟悉,主要是一些类型转换什么的,所以这个题目用 java 写起来显得比较慢,如果用python的话肯定写的很快。
//      所以这也是为什么要用 java 来做题目的原因,边做边学吧。
// 1.     1
// 2.     11
// 3.     21
// 4.     1211
// 5.     111221
// 6.     312211
// 7.     13112221
// 8.     1113213211
// 9.     31131211131221
//10.     13211311123113112211


import java.util.ArrayList;
import java.util.List;

public class CountAndSay {
    public String countAndSay(int n) {
        String res;
        if (n == 1)
            return "1";
        if (n==2)
            return "11";
        res = "11";
        for (int i = 3; i <= n; i++) {
            res = count(res);
        }
        return res;
    }

    /**
     * 从上一代到下一代的函数,输入是上一代的 字符串,输出是下一代的字符串
     *
     * @param s
     * @return
     */
    public String count(String s) {
        String res;
        List<Character> ele = new ArrayList<Character>();
        char arr[] = s.toCharArray();
        int count = 1;
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                // 对于最后一个元素的特殊处理
                if (arr[i] == arr[i - 1]) {
                    ele.add(new Character((char) (count + 48)));
                    ele.add(new Character(arr[i]));
                } else {
                    ele.add('1');
                    ele.add(new Character(arr[i]));
                }
            } else {
                if (arr[i] == arr[i + 1]) {
                    count++;
                    continue;
                } else {
                    ele.add(new Character((char) (count + 48)));  //  这里的类型转换,JVM会自动将其当做 asc2码,所以要加一个 48
                    ele.add(new Character(arr[i]));
                    count = 1; // 计数复位
                }
            }

        }
        StringBuilder stringBuilder = new StringBuilder();
        for (Character e : ele) {
            stringBuilder.append(e);
        }
        res = new String(stringBuilder);
        return res;
    }

    public static void main(String args[]) {
        int a = 4;
        CountAndSay c = new CountAndSay();

        System.out.println(c.countAndSay(10));
    }
}

更好的方法

可以用 StringBuilder 对象来完成字符拼接成字符串的工作。而且 StringBuilder 可以向其中添加整数等非char类型的元素。
同时,遍历String的时候,可以从第一个向后遍历,这样就不用考虑最后一个元素的特殊情况,只需要在遍历结束后将Count 和 最后 一个元素 也加入。使得代码简洁了许多。

public String countAndSay(int n) {
    if(n<=0)
        return "";
    String curRes = "1";
    int start = 1;//从1开始算
    while(start < n){
        StringBuilder res = new StringBuilder();
        int count = 1;
        for(int j=1;j<curRes.length();j++){
            if(curRes.charAt(j)==curRes.charAt(j-1))
                count++;
            else{
                res.append(count);
                res.append(curRes.charAt(j-1));
                count = 1;
            }
        }
        res.append(count);
        res.append(curRes.charAt(curRes.length()-1));
        curRes = res.toString();
        start++;
    }
    return curRes;
}

相关文章

网友评论

      本文标题:38. Count And Say 问题

      本文链接:https://www.haomeiwen.com/subject/kjibnctx.html