1. LeetCode
–38外观数列
题目连接:https://leetcode-cn.com/problems/count-and-say/
题目类型:简单数列问题(
2020字节跳动校招笔试题
)
1.1 问题描述
给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
- 注意:整数序列中的每一项将表示为一个
字符串。
- 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
- 前五项如下:
1
11
21
1211
111221
第一项是数字 1
描述前一项,这个数是 1 即 “一个 1 ”,记作 11
描述前一项,这个数是 11 即 “两个 1 ” ,记作 21
描述前一项,这个数是 21 即 “一个 2 一个 1 ” ,记作 1211
描述前一项,这个数是 1211 即 “一个 1 一个 2 两个 1 ” ,记作 111221
1.2 代码实现
class Solution {
public String countAndSay(int n) {
StringBuffer sb = new StringBuffer();
// 后面添加个0防止sb.charAt(j+1)出现下标越界问题
sb.append("10");
// 根据 n 判断循环次数
for (int i = 1; i < n; i++) {
// 记录数字的个数,默认是 1
int count = 1;
String temp = "";
// 获取StringBuffer的长度
int length = sb.length();
// 12110
// 根据StringBuffer的长度决定循环次数,注意sb初始值后面有个0,所以length-1
for (int j = 0; j < length-1; j++) {
// 判断StringBuffer第一个和后一个是否相同,如果相同count++
if (sb.charAt(j) == sb.charAt(j + 1)) {
count++;
// 如果与后一个不相同直接输出个数与该位置的值,即得到有‘一个1’
}else{
// 111221
temp += "" + count + sb.charAt(j) ;
// 每对一位数对count设置默认值1
count = 1;
}
}
// 清空StringBuffer中的数据
sb.delete(0,sb.length());
sb.append(temp+"0");
}
return sb.toString().substring(0,sb.length()-1);
}
}
1.3 测试代码
public class Main{
public static void main(String[] args) {
Solution solution = new Solution();
String result = solution.countAndSay(4);
System.out.println("result = " + result);
}
}
1.4 结果分析
结果:
- 执行用时:21 ms, 在所有 Java 提交中击败了17.96%的用户
- 内存消耗:40.3 MB, 在所有 Java 提交中击败了5.41%的用户
下面是大佬的题解:比较好理解,
执行时间为2ms
。
class Solution {
public static String countAndSay(int n) {
StringBuilder sb = new StringBuilder();
sb.append("1");
for (int i = 2; i <= n ; i++) {
String currentStr = new String(sb);
sb.delete(0,ans.length());
int num = 0;
char currentChar = currentStr.charAt(0);
for (char c : currentStr.toCharArray()) {
if(c == currentChar){
num++;
}
else{
sb.append((char)('0'+num));
sb.append(currentChar);
currentChar = c;
num = 1;
}
}
sb.append((char)('0'+num));
sb.append(currentChar);
}
return sb.toString();
}
}