一、我以为只有我不会,实际上只有我不会
今天晚上看到一个 LeetCode 的题:
题目链接:外观数列

他给的样例是这样的:

不知道大家与没有注意到 1 <= n <= 30。我当时还没注意这个,看了半天的题目还是没看懂,于是去评论区看了看,果然,评论区的大佬从来没让我失望:

好家伙,我直接好家伙。顿时想起了一句话,社会很单纯,复杂的是人。个个都是人才啊!我咋没想到这种方法呢?
我笑了半天,想想毕竟我是来评论区学技术的,于是接着看评论:


真是笑死个人了。不过当我看了看这几个数据的时候:


我知道事情并没有想象的那么简单,有些人说不会是真不会(比如我),而有些人,就是有些人,嘴上说着不会,实际上提交了打表的代码,暗地里用了好多种解法(比如说什么递归,迭代)。像极了期末考试时发呆的我。
二、言归正传,我们来看下这个题。
他的意思就是:
传入一个正数 n,String 的初始值是 String = "1";
比如传入的 n 为 4 的时候:
n == 2:我们以String = “1” 作为参考值,此时描述它就为 1 个 1,即11;
n == 3:我们以上一次 11 作为参考值,此时描述它为 2 个 1,即 21;
n == 4:我们以上一次 21 作为参考值,此时的描述为 1个 2 ,1 个 1,即1211;
重点:以上一个字符串作为参考值
思路:
1、初始化 String res = "1";即:
String res = "1";
2、第一个循环,n 初始值为 4,即要描述四次,第一次就是 1,所以有:
if(n == 1) {
return res;
}
3、定义一个循环,表示要描述的次数:
for(int i = 2;i <= n;i++) {
//我们要做点什么呢?
}
4、我们之前说过要以上一次的描述为参考,这次描述的就是这个参考,所以需要定义:
char prev = res.charAt(0);
int count = 1;
StringBuilder sb = new StringBuilder();
5、我们来遍历参考
for(int j = 1;j < res.length();j++) {
if(prev == res.charAt(j) {
count++;
}else {
sb.append(count).append(prev);
prev = res.charAt(i);
count = 1;
}
}
6、结束这次描述参考,我们就需要将结果更新,作为下一次循环的参考
sb.append(count).append(prev);
res = sb.toString();
7、外层循环结束,返回结果
return res;
三、我们来把代码组装起来
public static String countAndSay(int n) {
String res = "1";
if(n == 1) {
return res;
}
for(int i = 2;i <= n;i++) {
//用来组装当前的结果
StringBuilder sb = new StringBuilder();
//判断第一个和第二个字符是否相等
char prev = res.charAt(0);
//不管想不想等 至少都是有一个的
int count = 1;
for(int j = 1;j < res.length();j++) {
if(res.charAt(j) == prev) {
count++;
}else {
//不相等先把这个加上去
sb.append(count).append(prev);
//让prev == 与之前不相等的这个字符开始循环
prev = res.charAt(j);
//并且重置count
count = 1;
}
}
//如果一直相等 例如1211 for循环走完 然后sb再把count和prev添加进去
sb.append(count).append(prev);
res = sb.toString();
}
return res;
}
建议读懂题后,如果还是没有思路,把测试用例带入代码调试走两遍。虽说不是大彻大悟,至少可以大概理解。
老规矩,来自小白的理解。多多指教!
浙公网安备 33010602011771号