day32 2023/03/04
一、买卖股票的最佳时机Ⅱ
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
分析如下:
那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 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;
}
};
二、跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
分析如下:
局部最优推出全局最优,找不出反例,试试贪心!
如图:
代码如下:
class Solution {
public:
bool canJump(vector<int>& nums) {
if(nums.size()==1) return true;
int cover=0;
for(int i=0;i<=cover;i++)
{
cover=max(i+nums[i],cover);
if(cover>=nums.size()-1) return true;
}
return false;
}
};
三、跳跃游戏Ⅱ
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
分析如下:
从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!
这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。
如图:
图中覆盖范围的意义在于,只要红色的区域,最多两步一定可以到!(不用管具体怎么跳,反正一定可以跳到)
代码如下:
class Solution {
public:
int jump(vector<int>& nums) {
if(nums.size()==1) return 0;
int curDis=0;//当前可以覆盖到的最大范围下标
int nextDis=0;//下一步可以覆盖到的最大范围下标
int res=0;//记录走的最大步数
for(int i=0;i<nums.size();i++)
{
nextDis=max(nums[i]+i,nextDis);
if(i==curDis)
{
if(curDis<nums.size()-1)
{
res++;
curDis=nextDis;
if(nextDis>=nums.size()-1)
break;
}
else break;
}
}
return res;
}
};