每日一题——外观数列

菜鸡每日一题系列打卡38

每天一道算法题目 

小伙伴们一起留言打卡

坚持就是胜利,我们一起努力!

题目描述(引自LeetCode)

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

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


解释:
1被读作"one 1" ("一个一"),即11。
11被读作"two 1s" ("两个一"),即21。
21被读作"one 2","one 1" ("一个二","一个一"),即1211。

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

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

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


示例 2:
输入: 4
输出: "1211"
解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。

题目分析

由题意可知,本题是一道外观数列定义的题目,因此,关键点是根据定义找到外观数列的规律,并将其用程序进行实现。根据外观数列的定义,求第n项的前提是知道第n-1项,因此,可以考虑递归的方式进行解决,而每次递归调用的逻辑,无非就是获取前一项的结果并进行遍历,“读取”其外观。

代码实现

class Solution {


    public String countAndSay(int n) {
        if (n == 1) return "1";
        StringBuilder builder = new StringBuilder();
        int flag = 0, i;
        String s = countAndSay(n - 1);
        for (i = 1; i < s.length(); i++) {
            if (s.charAt(flag) != s.charAt(i)) {
                builder.append(i - flag).append(s.charAt(flag));
                flag = i;
            }
        }
        return builder.append(i - flag).append(s.charAt(flag)).toString();
    }
    
}

代码分析

对代码进行分析,每次递归调用过程中,循环执行的次数与前一项结果的长度有关,空间占用亦与之有关,时间复杂度与空间复杂度均为指数级别。

执行结果

每日一题——外观数列_第1张图片

每日一题——外观数列_第2张图片

学习 | 工作 | 分享

????长按关注“有理想的菜鸡

只有你想不到,没有你学不到

你可能感兴趣的:(算法)