leetcode第38题

简介: 难在了题目是什么意思呢?初始值第一行是 1。第二行读第一行,1 个 1,去掉个字,所以第二行就是 11。第三行读第二行,2 个 1,去掉个字,所以第三行就是 21。第四行读第三行,1 个 2,1 个 1,去掉所有个字,所以第四行就是 1211。第五行读第四行,1 个 1,1 个 2,2 个 1,去掉所有个字,所以第五航就是 111221。第六行读第五行,3 个 1,2 个 2,1 个 1,去掉所以个字,所以第六行就是 312

image.png

难在了题目是什么意思呢?

初始值第一行是 1。

第二行读第一行,1 个 1,去掉个字,所以第二行就是 11。

第三行读第二行,2 个 1,去掉个字,所以第三行就是 21。

第四行读第三行,1 个 2,1 个 1,去掉所有个字,所以第四行就是 1211。

第五行读第四行,1 个 1,1 个 2,2 个 1,去掉所有个字,所以第五航就是 111221。

第六行读第五行,3 个 1,2 个 2,1 个 1,去掉所以个字,所以第六行就是 312211。

然后题目要求输入 1 - 30 的任意行数,输出该行是啥。

解法一 递归

可以看出来,我们只要知道了 n - 1 行,就可以写出第 n 行了,首先想到的就是递归。

第五行是 111221,求第六行的话,我们只需要知道每个字符重复的次数加上当前字符就行啦。

1 重复 3 次,就是 31,2 重复 2 次就是 22,1 重复 1 次 就是 11,所以最终结果就是 312211。

publicStringcountAndSay(intn) {
//第一行就直接输出if (n==1) {
return"1";
    }
//得到上一行的字符串Stringlast=countAndSay(n-1);
//输出当前行的字符串returngetNextString(last);
}
privateStringgetNextString(Stringlast) {
//长度为 0 就返回空字符串if (last.length() ==0) {
return"";
    }
//得到第 1 个字符重复的次数intnum=getRepeatNum(last);
// 次数 + 当前字符 + 其余的字符串的情况returnnum+""+last.charAt(0) +getNextString(last.substring(num));
}
//得到字符 string[0] 的重复个数,例如 "111221" 返回 3privateintgetRepeatNum(Stringstring) {
intcount=1;
charsame=string.charAt(0);
for (inti=1; i<string.length(); i++) {
if (same==string.charAt(i)) {
count++;
        } else {
break;
        }
    }
returncount;
}

时间复杂度:

空间复杂度:O(1)。

解法二 迭代

既然有递归,那就一定可以写出它的迭代形式。

publicStringcountAndSay(intn) {
Stringres="1";
//从第一行开始,一行一行产生while (n>1) {
Stringtemp="";
for (inti=0; i<res.length(); i++) {
intnum=getRepeatNum(res.substring(i));
temp=temp+num+""+res.charAt(i);
//跳过重复的字符i=i+num-1;
        }
n--;
//更新res=temp;
    }
returnres;
}
//得到字符 string[0] 的重复个数,例如 "111221" 返回 3privateintgetRepeatNum(Stringstring) {
intcount=1;
charsame=string.charAt(0);
for (inti=1; i<string.length(); i++) {
if (same==string.charAt(i)) {
count++;
        } else {
break;
        }
    }
returncount;
}

时间复杂度:

空间复杂度:O(1)。

递归里边又用了一个递归,我觉得这点有点意思。

相关文章
|
9月前
|
C++ Python
leetcode-283:移动零
leetcode-283:移动零
32 0
|
算法
leetcode第40题
会发现出现了很多重复的结果,就是因为没有跳过重复的 1。在求 opt [ 1 ] 的时候就变成了 [ [ 1 ],[ 1 ] ] 这样子,由于后边求的时候都是直接在原来每一个列表里加数字,所有后边都是加了两次了。
leetcode第40题
|
存储 算法
leetcode第43题
个位乘个位,得出一个数,然后个位乘十位,全部乘完以后,就再用十位乘以各个位。然后百位乘以各个位,最后将每次得出的数相加。十位的结果要补 1 个 0 ,百位的结果要补两个 0 。相加的话我们可以直接用之前的大数相加。直接看代码吧。
102 0
leetcode第43题
leetcode第7题
为什么呢?倒置过来不应该是 9646324351 吗。其实题目里讲了,int 的范围是 [-2^{31} ,2^{31}-1][−2 ​31 ​​ ,2 ​31 ​​ −1] 也就是 [-2147483648,2147483647][−2147483648,2147483647] 。明显 9646324351 超出了范围,造成了溢出。所以我们需要在输出前,判断是否溢出。 问题的关键就是下边的一句了。 rev = rev * 10 + pop; 为了区分两个 rev ,更好的说明,我们引入 temp 。 temp = rev * 10 + pop; rev = temp; 我们对 t
106 0
leetcode第7题
|
存储 算法 Java
leetcode第29题
这道题看起来简单,却藏了不少坑。首先,我们用一次一次减造成了超时,然后我们用递归实现了加倍加倍的减,接着由于 int 表示的数的范围不是对称的,最小的负数并不能转换为对应的相反数,所以我们将之前的算法思路完全逆过来,正数边负数,大于变小于,还是蛮有意思的。
109 0
leetcode第29题
【LeetCode】Reconstruct Itinerary(332)
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK.
102 0
leetcode第39题
对回溯法又有了更深的了解,一般的架构就是一个大的 for 循环,然后先 add,接着利用递归进行向前遍历,然后再 remove ,继续循环。而解法二的动态规划就是一定要找到递进的规则,开始的时候就想偏了,导致迟迟想不出来。
leetcode第39题
|
9月前
leetcode-475:供暖器
leetcode-475:供暖器
59 0
leetcode第44题
时间复杂度:text 长度是 T,pattern 长度是 P,那么就是 O(TP)。 空间复杂度:O(TP)。 同样的,和第10题一样,可以优化空间复杂度。
108 0
leetcode第44题
单链表反转 LeetCode 206
单链表反转 LeetCode 206
85 0