The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, ...
1is read off as"one 1"or11.
11is read off as"two 1s"or21.
21is read off as"one 2, thenone 1"or1211.
Given an integer n, generate the n th sequence.
Note: The sequence of integers will be represented as a string.
刚开始没看懂题目的意思,后来才发现n是指读的次数。
例如:n =1时候,结果为1
n =2时候,以前一次结果1为基础,一个1,即结果为11
n =3时候,以前一次结果11为基础,两个1,即结果为21
n =4时候,以前一次结果21为基础,一个2一个1,即结果为1211
n =5时候,以前一次结果1211为基础,一个1一个2两个1,即结果为111221
以此类推.........
解题思路:每次读取前一次序列结果的时候,通过循环遍历这个序列,设置一个计数标志count, 初始值置为 1,其代表序列中每个字符出现次数为1,遍历序列,若相邻的两个字符相等,则执行count++操作;否则将“count(次数)+字符”组成的字符串追加到结果字符串后面。
之前采用String对字符串进行初始化,然后采用“+”操作对字符串进行拼接,发现程序运行超时了。。。后来去网上查找了下资料,发现用String进行字符拼接的时候会产生很多中间对象问题,而StringBuffer就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类,提供append和add方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上了synchronized。但是保证了线程安全是需要性能的代价的。在很多情况下我们的字符串拼接操作不需要线程安全,这时候StringBuilder登场了,StringBuilder是JDK1.5发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。
String,StringBuffer,StringBuilder的区别:https://blog.csdn.net/weixin_42047723/article/details/93629210
JAVA代码
使用String(程序运行超时,不通过X):
public class Solution {
public String countAndSay(int n) {
if(n < 0)
return "";
String str = "1";
for(int i = 1; i < n; i++){
int count = 1;
String t = "";
int len = str.length();
for(int j = 1; j < len; j++){
if(str.charAt(j) == str.charAt(j-1)){
count ++;
}
else{
t += count + str.charAt(j-1);
count = 1;
}
}
//读序列最后一个字符
t += count + str.charAt(len - 1);
str = t;
}
return str;
}
}
使用StringBuilder(程序运行通过√,使用StringBuffer也可行):
public class Solution {
public String countAndSay(int n) {
if(n < 0)
return "";
StringBuilder str = new StringBuilder("1");
for(int i = 1; i < n; i++){
int count = 1;
StringBuilder t = new StringBuilder();
int len = str.length();
for(int j = 1; j < len; j++){
if(str.charAt(j) == str.charAt(j-1)){
count ++;
}
else{
t.append(count).append(str.charAt(j-1));
count = 1;
}
}
//读序列的最后一个字符
t.append(count).append(str.charAt(len - 1));
str = t;
}
return str.toString();
}
}