leetcode热题100刷题笔记(1)

53.最大子序和

在这里插入图片描述

思路:

最大子序列和是一个非常经典的动态规划问题,是应该时刻牢记于心的:
此题目中,首先定义dp数组,dp[i]的含义代表 “以nums[i]为结尾的子串的最大序列和”,由此不难发现,dp[i]要么等于dp[i-1]+nums[i](dp[i-1]>=0),要么就等于nums[i] (dp[i-1]<0),所以,状态转移方程也不难写出:

dp[i] = max(dp[i-1]+nums[i],nums[i]);

有了状态转移方程,动态规划就不是难事了

代码:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int maxSum = INT_MIN;
        int len = nums.size();
        vector<int> dp(len);
        dp[0] = nums[0];
        for(int i=1;i<len;i++){
            dp[i] = max(dp[i-1]+nums[i],nums[i]);
            maxSum = dp[i]>maxSum?dp[i]:maxSum;
        }
        return max(maxSum,nums[0]);
    }
};

55.跳跃游戏

在这里插入图片描述

思路:

只需要从后向前遍历,用lastpos来代表当前位置需要到达的最远处,如i+nums[i]>=lastpos,就说明可以到达,向前更新lastpos,直到lastpos为0

代码:

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int lastpos = nums.size()-1;
        for(int i=nums.size()-1;i>=0;i--){
            if(i+nums[i]>=lastpos){
                lastpos=i;
            }
        }
        return lastpos == 0;
    }
};

相关题目:跳跃游戏II:

在这里插入图片描述

思路:

此题可以利用贪心的思想来解决:
对于当前起跳点i来说,能够跳到的最远的距离应该是i+nums[i],而在i到nums[i]之间的这些数,又可以作为新的起跳点,我们只需要在这些新的起跳点中,找到可以到达距离最远的那个(也就是i+nums[i]最大的),因为这样在下一次可以获得最大的起跳范围,例如下图中的

2,3,1,1,4

起跳点为2,则下一次可以跳到3,1,而
1+nums[1]=1+3=4,
2+nums[2]=2+1=3,
所以选择从3的位置起跳,用begin标志起跳区间的起点,用end标记起跳区间的终点,用temp标记begin与end之间i+nums[i]的最大值,则下一次迭代中,begin=end,end=temp+1;
完成赋值也就代表着完成了一次跳跃,令ans++

代码:

Alt

class Solution {
public:
    int jump(vector<int>& nums) {
        int ans=0,begin=0,end=1;
        while(end<nums.size()){
            int temp = 0;
            for(int i=begin;i<end;i++){
                temp = max(temp,i+nums[i]);
            }
            begin = end;
            end = temp+1;
            ans++;
        }
        return ans;
    }
};

56.合并区间

在这里插入图片描述

思路:

为了方便处理,首先利用sort对intervals按照字典序进行排序,之后对二维向量从前往后进行遍历,遍历的过程中,对于能否进行合并做出判断
能够合并的条件是:
下一个区间的左端点值小于等于当前区间的右端点值
合并的方法是:
如果能够合并,则将当前区间的右端点改成:max(当前区间的右端点,下一个区间的右端点)
这样,区间包含与区间交错的情况都包括进去了
由于刚开始进行了sort,所以不用特意考虑右端点

代码

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> ans;
        //特判
        if(intervals.empty()) return ans;
        sort(intervals.begin(),intervals.end());
        for(int i=0;i<intervals.size();i++){
            vector<int> temp = intervals[i];
            while(i+1<intervals.size() && temp[1]>=intervals[i+1][0]){
                ++i;
                temp[1] = max(temp[1],intervals[i][1]);
            }
            ans.push_back(temp);
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值