38 报数
报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
- 1
- 11
- 21
- 1211
- 111221
1 被读作 “one 1” (“一个一”) , 即 11。
11 被读作 “two 1s” (“两个一”), 即 21。
21 被读作 “one 2”, “one 1” (“一个二” , “一个一”) , 即 1211。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
这道题是不断利用上一个结果推出下一个。我非常明白操作原理,但感觉难点是在如何直接输出第n行的数字。
我首先想到的解决方法是利用循环:
class Solution {
public:
string countAndSay(int n) {
string lin="1";//表示每行是什么
string num;//表示最后输出的结果
if(n==1) return "1";
for(int i=1;i<n;i++){ //行循环
int count=1;
for(int j=0;j<lin.length();j++){ //里面列循环
if(lin[j]==lin[j+1]){
count++;
}
else{
num+=to_string(count)+lin[j];
count=1;
}
}
lin=num;
num="";
}
return lin;
}
};
实现结果:效率还不错
之后要学习别人写的啦,一种递归思想值得学习(相对于自己的来说就是不用for循环和每次重制lin了),代码如下(为了方便自己看懂,把人家用的字母改成和自己习惯的了):
class Solution {
public:
string countAndSay(int n) {
if(n==1) return "1";
string lin=countAndSay(n-1); //==重点,主要是这一步的递归思想==
int count = 1;//计数
string num;//存放结果
for(int i=0;i<lin.size();i++)
{
if(lin[i]==lin[i+1])//计算有多少个相同数字
{
count++;
continue;
}
else
{
if(lin[i]!=lin[i+1])
{
num+=to_string(count)+lin[i];
count=1;
}
}
}
return num;
}
};
运行结果:可以看出,递归还是在空间上占用的更多。
53 最大子序和
这道题的意思是给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
开始我的做题思路是有些利用冒泡的思想,进行内外两次排序,始终记录和最大的数即可。代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max=nums[0];
for(int i=0;i<nums.size();i++){
int sum=0;
for(int j=i;j<nums.size();j++){
sum+=nums[j];
if(sum>=max)
max=sum;
}
}
return max;
}
};
执行结果如下:可以看到执行时间非常长,效率不高。
之后看各位大佬的解答方法,发现这应该是一道应用动态规划思想解题的题。(这是一个很大块的问题,B站上有讲的很不错的视频,建议大家去听呀~)
代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0)
return NULL;
int sum=0;
int res=INT_MIN;
for(int i=0;i<nums.size();i++)
{
sum=max(sum+nums[i],nums[i]);
res=max(res,sum);
}
return res;
}
};