LeetCode 外观数列

197 阅读2分钟

LeetCode 外观数列

外观数列(Count and Say)是一道常见的算法面试题,也是LeetCode上的一道经典题目,它的难度为简单。这道题的目的是给定一个正整数n,输出前n项的外观数列。

外观数列的定义如下:

  • 第一个元素是1,即s1 = "1";
  • 第二个元素是读出s1的数字个数,即s2 = "11";
  • 第三个元素是读出s2的数字个数,即s3 = "21";
  • 第i个元素是读出si-1的数字个数,即si。

以下是前五项的外观数列:

  • 1
  • 11
  • 21
  • 1211
  • 111221

要求:输入正整数n,输出前n项的外观数列。

LeetCode的题目链接:leetcode.com/problems/co…

  1. 算法思想

首先,我们可以从外观数列的定义入手,根据前一项元素推导出当前项的元素。具体来说,我们需要对当前字符串进行遍历,用一个计数器count记录重复元素的个数,用一个StringBuilder来储存新的字符串,然后根据计数器的值和元素的值来构造新的字符串。

下面用第四项外观数列为例说明算法思想:

  • 对第三项进行遍历,分别是"2"和"1";
  • 遍历"2"时,发现前面有一个相同的元素"2",计数器count加1;
  • 继续遍历,发现下一个元素不同,就将计数器的值和当前元素的值存储起来,即"12";
  • 遍历到"1"时,同样的操作,得到"11";
  • 最后将"12"和"11"拼接起来,即得到第四项外观数列的元素:"1211"。
  1. 代码实现

下面使用Java语言实现算法思想所述的算法:

class Solution {
    public String countAndSay(int n) {
        if (n == 1) {
            return "1";
        }
        String prev = countAndSay(n - 1);
        StringBuilder sb = new StringBuilder();
        int count = 1;
        for (int i = 1; i < prev.length(); i++) {
            if (prev.charAt(i - 1) == prev.charAt(i)) {
                count++;
            } else {
                sb.append(count).append(prev.charAt(i - 1));
                count = 1;
            }
        }
        sb.append(count).append(prev.charAt(prev.length() - 1));
        return sb.toString();
    }
}

代码中的countAndSay()函数是递归实现的。在函数内部,首先判断n是否为1,如果是,直接返回字符串"1"。否则,递归调用countAndSay()函数,获取前一项外观数列的字符串prev。然后,我们通过遍历prev来计算当前项的外观数列元素,并将其储存在StringBuilder中并返回。

  1. 测试示例

下面给出几组测试示例,以验证代码的正确性:

输入:n = 1

输出:"1"

输入:n = 4

输出:"1211"

输入:n = 5

输出:"111221"

输入:n = 10

输出:"13211311123113112211"

以上就是关于外观数列的算法学习文章,希望对你的LeetCode算法学习有所帮助。