leetcode 376摆动序列,最大子序列和,跳跃游戏

在这里插入图片描述
技巧:

  1. 只需要统计摆动序列长度,故并不需要对原数组有什么修改
  2. 若数组长度为二,则摆动长度为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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值