机考刷题之 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];
    }
};

结果

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

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

相关推荐
2501_911088232 小时前
C++中的代理模式变体
开发语言·c++·算法
客卿1232 小时前
岛屿问题--bfs的应用--二维网络题目学习
学习·算法·宽度优先
无限进步_2 小时前
【C++】只出现一次的数字 III:位运算的巧妙应用
数据结构·c++·git·算法·leetcode·github·visual studio
2401_900151542 小时前
代码覆盖率工具实战
开发语言·c++·算法
进击的小头2 小时前
第8篇:PI控制器设计实战演练
c语言·python·mcu·算法
乌萨奇也要立志学C++2 小时前
【洛谷】图论 图论最短路算法全解:从单源 Dijkstra 到多源 Floyd 模板与实战
算法·图论
AI科技星2 小时前
基于v=c空间本底光速螺旋运动的宏观力方向第一性原理推导:太阳系与地球系统的全维度观测验证
人工智能·线性代数·算法·机器学习·平面
Epiphany.5562 小时前
炸雷!(地址映射+dfs搜索)
算法
Crazyong2 小时前
FreeRTOS-互斥量-2
算法