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

LeetCode 55:

题目

分析

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

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

代码

贪心:

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天在内,这之前都是这种状态,比如dpi1就是在第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];
    }
};

结果

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

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

相关推荐
先吃饱再说10 小时前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰13 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术14 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六17 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术18 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize19 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考1 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队1 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode