给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
视频讲解https://www.bilibili.com/video/BV1ev4y1C7na/?spm_id_from=333.999.0.0文章讲解https://programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII.html
- 思路:分解
-
假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
-
以每天为单位分解利润
-
收集正利润
-
- 代码:
// 贪心解法
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;
}
};
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断 是否能够到达 最后一个位置。
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
视频讲解https://www.bilibili.com/video/BV1VG4y1X7kB/?spm_id_from=333.999.0.0文章讲解https://programmercarl.com/0055.%E8%B7%B3%E8%B7%83%E6%B8%B8%E6%88%8F.html#%E6%80%9D%E8%B7%AF
- 思路:
- 法一:跳跃覆盖范围究竟可不可以覆盖到终点
- 法二:维护一个 result 数组,记录从每个下标能否到达终点,从后往前填充该数组;若跳不过连续的 false 位置,则为 false;返回 result[0] 即可。
- 代码:
// 法一:
class Solution {
public:
bool canJump(vector<int>& nums) {
// 最远能覆盖到的下标
int cover = 0;
for (int i = 0; i <= cover; ++i) {
// 说明可以覆盖到终点了
// 不用单独处理nums.size() == 1
if (cover >= nums.size() - 1) {
return true;
}
cover = max(i + nums[i], cover);
}
return false;
}
};
// 法二:
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<bool> result(nums.size(), false);
result[nums.size() - 1] = true;
int count = 0;
for (int i = nums.size() - 2; i >= 0; --i) {
// 能跳过false位置
if (nums[i] > count) {
result[i] = true;
count = 0;
} else {
count++;
}
}
return result[0];
}
};
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用 最少的跳跃次数 到达数组的最后一个位置。
视频讲解https://www.bilibili.com/video/BV1Y24y1r7XZ/?spm_id_from=333.999.0.0&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0045.%E8%B7%B3%E8%B7%83%E6%B8%B8%E6%88%8FII.html
- 思路:维护两个变量①当前步能到达的最远位置②下一步能到达的最远位置
- 当 i == 当前步能到达的最远位置👉需要再跳一步
- 用下一步更新当前步,并且步数++
- 代码:
class Solution {
public:
int jump(vector<int>& nums) {
int curDistance = 0; // 当前覆盖的最远距离下标
int ans = 0; // 记录走的最大步数
int nextDistance = 0; // 下一步覆盖的最远距离下标
for (int i = 0; i < nums.size() - 1; i++) { // 注意这里是小于nums.size() - 1,这是关键所在
nextDistance = max(nums[i] + i, nextDistance); // 更新下一步覆盖的最远距离下标
if (i == curDistance) { // 遇到当前覆盖的最远距离下标
curDistance = nextDistance; // 更新当前覆盖的最远距离下标
ans++;
}
}
return ans;
}
};