机考刷题之 23&24&25 LeetCode 55&213&123

LeetCode 55:

题目

分析

推荐用贪心,思路就是不断去更新能够跳到的最大值,如果大于等于n-1,那么就能跳到最后,反之不能。

但是我自己写的时候,是用的递归,就是倒着算回去,这在这道题中不是最优解,但如果nums数组含义变了,变成nums[i]表示"只能从第i格跳nums[i]步",那就只能用这个更好

代码

贪心:

cpp 复制代码
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int farthest = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (i > farthest) return false;//采用最长的组合都跳不到第i格
            farthest = max(farthest, i + nums[i]);//更新最长的组合
        }
        return true;
    }
};

递归:

cpp 复制代码
class Solution {
private:
    bool recursion(vector<int> & array,int pos){
        if(pos == 0) return 1;
        for(int i = 0;i<pos;i++){
            if(array[i] >= pos - i)
            return recursion(array,i);
        }
        return 0;
    }
public:
    bool canJump(vector<int>& nums) {
        return recursion(nums,nums.size()-1);
    }
};

结果

贪心:

递归:

LeetCode 213:

题目

分析

和I区别不大,但是多了一个首尾相连,这导致两端不能同时被抢,在写完主体后,在这里被卡住了,看了题解是要么抢第一家(也就是考虑0-n-2)、要么抢最后一家(也就是考虑1-n-1),然后两个来取最大值。(此时两个都不抢已经被隐式包含了)

代码

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if (n == 1) return nums[0];
        if (n == 2) return max(nums[0], nums[1]);

        // 情况1:不抢第一家 → [1, n-1]
        vector<int> nums1(nums.begin() + 1, nums.end());
        // 情况2:不抢最后一家 → [0, n-2]
        vector<int> nums2(nums.begin(), nums.end() - 1);

        return max(robLinear(nums1), robLinear(nums2));
    }

private:
    int robLinear(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> dp(n, vector<int>(2, 0));
        dp[0][1] = nums[0];
        for (int i = 1; i < n; ++i) {
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]);
            dp[i][1] = dp[i-1][0] + nums[i];
        }
        return max(dp[n-1][0], dp[n-1][1]); // 更简洁,不用排序
    }
};

结果

LeetCode 123:

题目

分析

感觉这些依靠前一天或者前面的状态的dp问题都是一个套路,重点是规划好合适dp数组对应的状态,这里的dp数组就是0-4分别对应:无操作、第一次买、第一次卖、第二次买、第二次卖。

注意这里是指包括第i天在内,这之前都是这种状态,比如dp[i][1]就是在第i天以及之前就已经买入了或者第i天才买入,诸如此类。

代码

cpp 复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if(n<=1)return 0;
        vector<vector<int>>dp(n,vector<int>(5,0));//0-在此之前一直(包括现在)一直都没有操作
                                                  //1-在此之前一直(包括现在)第一次买入
                                                  //2-在此之前一直(包括现在)第一次卖出
                                                  //3-在此之前一直(包括现在)第二次买入
                                                  //4-在此之前一直(包括现在)第二次卖出
        dp[0][1] = -prices[0];
        dp[0][3] = -prices[0];
        for(int i = 1;i < n;i++){
            dp[i][0] = dp[i-1][0];
            dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);//这一天第一次买入或者保持
            dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i]);//这一天第一次卖出或者保持
            dp[i][3] = max(dp[i-1][3],dp[i-1][2]-prices[i]);//这一天第二次买入或者保持
            dp[i][4] = max(dp[i-1][4],dp[i-1][3]+prices[i]);//这一天第二次卖出或者保持
        }
        return dp[n-1][4];
    }
};

结果

还有一种是用滚动变量来做,代码:

这个在复杂度上肯定要好得多,不过我的代码是比较"泛用"吧(或许这个也挺泛用,但我不熟悉,嘻嘻)

相关推荐
圣保罗的大教堂9 分钟前
leetcode 1855. 下标对中的最大距离 中等
leetcode
智者知已应修善业1 小时前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
.5482 小时前
## Sorting(排序算法)
python·算法·排序算法
wuweijianlove2 小时前
算法的平均复杂度建模与性能回归分析的技术7
算法·数据挖掘·回归
子琦啊2 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
code_pgf4 小时前
Octo 算法详解-开源通用机器人策略模型技术报告
算法·机器人·开源
嘻嘻哈哈樱桃4 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划
脱氧核糖核酸__4 小时前
LeetCode热题100——234.回文链表(两种解法)
c++·算法·leetcode·链表
IronMurphy4 小时前
【算法四十二】118. 杨辉三角 198. 打家劫舍
算法
电科一班林耿超4 小时前
第 16 课:动态规划专题(二)—— 子序列与子数组问题:面试最高频的 DP 题型
数据结构·算法·动态规划