给定一个正整数 n ,输出外观数列的第 n 项。

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

你可以将其视作是由递归公式定义的数字字符串序列:

  • countAndSay(1) = "1"
  • countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221
第一项是数字 1 
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"

描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 "3322251" 的描述如下图:

 

示例 1:

输入:n = 1
输出:"1"
解释:这是一个基本样例。

示例 2:

输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = 读 "1" = 一 个 1 = "11"
countAndSay(3) = 读 "11" = 二 个 1 = "21"
countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211"

 

提示:

  • 1 <= n <= 30
Related Topics
  • 字符串

  • 👍 765
  • 👎 0
  • 字符串模拟,这种阅读起来好像还是比直接sb拼接费劲不少。岂止费劲,还看得眼花。
    逻辑也是一样的,

    • 从’1’开始
    • 2个’1′ 就是 “21”
    • 然后“21”就是 1个’2’、1个’1’即“1211”
    • “1211”就是1个’1’、1个’2’、2个’1’,即“111221”
    • 后面依次类推

    class Solution {
        public String countAndSay(int n) {
            if (n == 1){
                return "1";
            }
            char[][] arr = new char[2][4500];
            arr[0][0] = '1';
            int i = 2;
            int cur = 1;
            int pre = 0;
            int preIdx = 0;
            int curIdx = 0;
            while (i <= n){
                cur = (i-1) % 2;
                pre = i % 2;
                preIdx = 0;
                curIdx = -1;
                while (arr[pre][preIdx] != '\u0000'){
                    char numChar = arr[pre][preIdx];
                    int count = 1;
                    while (arr[pre][preIdx] == arr[pre][preIdx+1]){
                        count++;
                        preIdx++;
                    }
                    preIdx++;
                    if (count > 10){
                        int countStringSize = 1;
                        int x = 10;
                        while (count/x != 0){
                            x *= 10;
                            countStringSize++;
                        }
                        curIdx++;
                        while (--countStringSize>=0){
                            arr[cur][curIdx + countStringSize] = (char)('0'+ count%10);
                            count = count / 10;
                        }
                        curIdx += countStringSize-1;
                    }else{
                        arr[cur][++curIdx] = (char)('0' + count);
                    }
                    arr[cur][++curIdx] = numChar;
                }
                i++;
            }
            char[] strChars = new char[curIdx+1];
            System.arraycopy(arr[cur],0,strChars,0,curIdx+1);
            return new String(strChars);
        }
    }