技巧:
- 只需要统计摆动序列长度,故并不需要对原数组有什么修改
- 若数组长度为二,则摆动长度为2。。则result初始为1(默认最右面有一个峰值),此时curDiff > 0 && preDiff <= 0,那么result++(计算了左面的峰值),最后得到的result就是2(峰值个数为2即摆动序列长度为2)
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int preDiff = 0;
int curDiff;
int res = 1;
for(int i = 1; i < nums.size(); i++){
curDiff = nums[i] - nums[i-1];
if((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)){
res++;
preDiff = curDiff; //不要写在if外面!!!
}
//若没有峰值即若单调,则直接跳过即可
}
return res;
}
};
思路:设一个res初始化为INT_MIN,sum = 0。需要注意的是只要当前sum < 0了,就得重新从i+1开始重新求sum,因为一个数加上负数只会越来越小
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum = 0;
int res = INT_MIN;
for(int i = 0; i < nums.size(); i++){
sum += nums[i];
//-2 1 0 4 3 5 6 1 5
if(sum > res){
//cout<<"tmp:"<<tmp<<endl;
res = sum;
//cout<<"res: "<<res<<endl;
}
if(sum <= 0){
sum = 0;
//cout<<"max: "<<max<<endl;
}
}
return res;
}
};
动态规划:
dp[i] 表示i之前包括i的最大子序和。而dp[i]可以由两个方向推导而来,一个是和前面的一起即dp[i-1] + nums[i],还有就是重新开始一段连续子数组,即nums[i]
故dp[i] = max(dp[i-1] + nums[i], nums[i]) 思路和贪心是一样的
class Solution {
public:
int maxSubArray(vector<int>& nums) {
//if(nums.size() == 1) return nums[0];
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
int maxSum = nums[0];
for(int i = 1; i < nums.size(); i++){
dp[i] = max(dp[i-1]
+ nums[i], nums[i]);
if(dp[i] > maxSum)
maxSum = dp[i];
}
return maxSum;
}
};
思路:不用考虑是跳几步,只要在当前位置的cover范围可以到达最后一个下标即可,即cover = nums.size() - 1;其中cover = max(cover, cover + nums[i])
如:
//初始cover = 0;
nums = [2,3,1,1,4]
i <= 0 i = 0. cover = max(0, i + nums[i]) = 2
i <= 2 i = 1. cover = max(2, i + nums[i]]) = 4. ( == nums.size() - 1)
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;
for(int i = 0; i <= cover; i++){
cover = max(cover, i + nums[i]);
if(cover >= nums.size() - 1)
return true;
}
return false;
}
};
跳跃游戏1是判断最后能否跳到最后一个位置,而2是假设可以达到最后一个位置,则最少跳跃次数是多少。
思路:从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!
这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
class Solution {
public:
int jump(vector<int>& nums) {
//[2, 3, 1, 1, 4]
//i = 0, cur = 0, next = 2;
//i == cur ans++ cur = next = 2;
//i = 1. cur = 2 next = 4
//i = 2. ans++. cur = 4;
int res = 0;
int curDis = 0;
int nextDis = 0;
for(int i = 0; i < nums.size(); i++){
nextDis = max(nextDis, nums[i]+ i);
if(i == curDis){
if(curDis != nums.size() - 1){
res++;
curDis = nextDis;
//cout<<"curDis: "<<curDis<<endl;
if(nextDis >= nums.size() - 1) break;
}
else break;
}
}
return res;
}
};