代码随想录算法训练营第24天|122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II、1005. K 次取反后最大化的数组和
LeetCode24
2025-02-24 21:14:17 星期一
题目描述:力扣24
文档讲解:代码随想录(programmercarl)122.买卖股票的最佳时机 II
视频讲解:《代码随想录》算法视频公开课:贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机 II
代码随想录视频内容简记
这个题的局部最优就是去寻找每一天价格的差值,如果是正值,那么就选,这样求得得全部最优就是收获的利润最大化
注意:
这个题和53最大子数组和有点像,但是有不一样的地方就是53是算的之前加起来的所有和是不是正值,而24买卖股票算的是每一天的差值是不是正值
LeetCode测试
点击查看代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
int result = 0;
for (int i = 1; i < prices.size(); i++) {
result += max(prices[i] - prices[i - 1], 0);
}
return result;
}
};
LeetCode55
题目描述:力扣55
文档讲解:代码随想录(programmercarl)55. 跳跃游戏
视频讲解:《代码随想录》算法视频公开课:贪心算法,怎么跳跃不重要,关键在覆盖范围 | LeetCode:55.跳跃游戏
错误思路
刚开始写的代码是这样的,想着遍历一边数组,只要有一个能覆盖终点就可以,但是事实不是这样的,搞错了。
bool canJump(vector<int>& nums) {
if (nums.size() == 1) return true;
for (int i = 0; i < nums.size() - 1; i++) {
if (nums.size() - 1 - i <= nums[i]) return true;
}
return false;
}
有一个用例是这样的,第一步就跳不过去,所以还是得用k哥cover的概念

正确思路
按照贪心的思路,局部最优就是每遍历一个元素,就取当前能覆盖到的最大范围,那么全局最优就是最后整个序列所能取到的最大覆盖范围
大致代码内容
点击查看代码
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;
if (nums.size() == 1) return true;
for (int i = 0; i <= cover; i++) {
cover = max(cover, i + nums[i]);
if (cover >= nums.size() - 1) return true;
}
return false;
}
};
LeetCode45
题目描述:力扣45
文档讲解:代码随想录(programmercarl)45.跳跃游戏 II
视频讲解:《代码随想录》算法视频公开课:贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏 II
代码随想录视频内容简记
这道题的和55跳跃游戏的不同就在于这里要输出跳到终点所需要的最少步数
这道题目贪的局部最优也是一个局部的最长步数,全局最优就是最后能覆盖到重点的最少步数
梳理
- 首先定义一个next,这个用来表示下一步的覆盖范围,但是这个next是不是之后真正下一步跳跃的起点(图中的3),还不能确定,因为在遍历的时候需要记录最大值。所以必须得把当前的覆盖范围遍历完之后才能确定。

-
图中的3用cur来表示当前跳跃的起始。
-
这里有一个小细节,为了避免在遍历完一个数的覆盖范围之后(比如第一个数2的覆盖范围是2,会遍历到1),从一般常识来讲,他需要重新回到3开始下一步的跳跃,按照我的想法,是应该同时把3的索引和他的值用max记录下来之后再做判断。这里就不对了
覆盖范围的定义:当前索引+跳跃距离
只有同时记录每一个数的索引和跳跃距离之和才行。
LeetCode测试
注意这个题有一个小细节,特意看了一下,为什么for循环中不再是cover了呢?因为力扣中明确说了
题目保证可以到达 nums[n-1]
点击查看代码
class Solution {
public:
int jump(vector<int>& nums) {
int next = 0, cur = 0, result = 0;
if (nums.size() == 1) return 0;
for (int i = 0; i < nums.size(); i++) {
next = max(nums[i] + i, next);
if (i == cur) {// 表示遍历完第一步
if (cur != nums.size() - 1) {// 表示cur没有遍历到最后一个数
result++;
cur = next;
} else {// 表示已经遍历到最后一个数
break;
}
}
}
return result;
}
};
LeetCode1005
题目描述:力扣1005
文档讲解:代码随想录(programmercarl)1005. K 次取反后最大化的数组和
视频讲解:《代码随想录》算法视频公开课:贪心算法,这不就是常识?还能叫贪心?LeetCode:1005.K次取反后最大化的数组和
代码随想录视频内容简记
这道题有两个贪心策略,第一个贪心的局部最优就是把所有具有最大绝对值的负数优先取反,使其变成正数,第二个局部最优就是把最小的正数进行重复取反。两个局部最优的全局最优都是取得最大的数组和
注意
在代码中有一个小细节,if (k % 2 == 1) nums[nums.size() - 1] *= -1;
这里直接判断奇偶性来对最后的数进行处理,而不是用while循环一次次乘-1
LeetCode测试
点击查看代码
class Solution {
private:
static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
int result = 0;
sort(nums.begin(), nums.end(), cmp);
for (int i = 0; i < nums.size(); i++) {
if (nums[i] < 0 && k > 0) {
nums[i] *= -1;
k--;
}
}
if (k % 2 == 1) nums[nums.size() - 1] *= -1;
for (int i = 0; i < nums.size(); i++) {
result += nums[i];
}
return result;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端