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…
- 算法思想
首先,我们可以从外观数列的定义入手,根据前一项元素推导出当前项的元素。具体来说,我们需要对当前字符串进行遍历,用一个计数器count记录重复元素的个数,用一个StringBuilder来储存新的字符串,然后根据计数器的值和元素的值来构造新的字符串。
下面用第四项外观数列为例说明算法思想:
- 对第三项进行遍历,分别是"2"和"1";
- 遍历"2"时,发现前面有一个相同的元素"2",计数器count加1;
- 继续遍历,发现下一个元素不同,就将计数器的值和当前元素的值存储起来,即"12";
- 遍历到"1"时,同样的操作,得到"11";
- 最后将"12"和"11"拼接起来,即得到第四项外观数列的元素:"1211"。
- 代码实现
下面使用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中并返回。
- 测试示例
下面给出几组测试示例,以验证代码的正确性:
输入:n = 1
输出:"1"
输入:n = 4
输出:"1211"
输入:n = 5
输出:"111221"
输入:n = 10
输出:"13211311123113112211"
以上就是关于外观数列的算法学习文章,希望对你的LeetCode算法学习有所帮助。