代码随想录Day32 | Leetcode 122、55、45
一、122 买卖股票的最佳时机II
题目链接:122 买卖股票的最佳时机II
核心:只要相邻两天的股票利润为正数,说明可以进行买卖股票,统计所有相邻元素之差为正数即可得到股票交易的最大值。
int maxProfit(vector<int>& prices) {
//贪心算法:只统计相邻两天的利润为正数的情况
int res=0;
for(int i=1;i<prices.size();++i)
{//遍历股票数组,从第二个元素开始,计算与前一个元素的利润,并取其正数
res+=max(prices[i]-prices[i-1],0);
}
return res;
}
二、55 跳跃游戏
题目链接:55 跳跃游戏
核心:无需关注需要怎样跳,只要跳的最大范围能覆盖到最后一个元素说明不管怎么跳都能到达最后一个下标元素。
定义一个变量cover记录每次跳跃能覆盖的最大范围,在遍历数组时只要该cover大于数组长度,说明已经覆盖到最后一个元素。
bool canJump(vector<int>& nums) {
//贪心算法
int cover=0; //每次跳跃能覆盖的最大范围
if(nums.size()==1)
return true;
for(int i=0;i<=cover;++i)
{
cover=max(i+nums[i],cover); //取原来的覆盖范围和当前元素覆盖范围的最大值
if(cover>=nums.size()-1)
return true; //只要cover覆盖到最后一个元素即可
}
return false;
}
三、45 跳跃游戏 II
题目链接:45 跳跃游戏 II
核心:与55 跳跃游戏相比,难度大大增加,主要是要求跳跃次数最小,这就需要关注如何跳,具体而言就是需要关注什么时候更新下一步。
首先,定义2个变量,其一是当前遍历元素的最大覆盖范围(下标),其二是下一步(不是下一个元素)的最大覆盖范围(下标)。
然后遍历数组,统计每个元素的最大覆盖范围,只有在当前元素移动到当前元素的最大覆盖范围时,才更新下一步,并且将下一步的最大覆盖范围赋值给当前元素的最大覆盖范围;并且更新后的当前元素最大覆盖范围到达最后一个元素时,说明这一步是最后一步,立即break退出循环。(由于每次移动下标跳到当前元素的最大覆盖范围时,更新后的最大覆盖范围都会判断是否到达最后一个元素,因此移动下标跳到当前元素的最大覆盖范围时,必然没到最后一个元素。)
int jump(vector<int>& nums) {
//贪心算法:何时统计跳跃次数是重点
int res=0;
if(nums.size()==1)
return res;
int curCover=0; //记录当前元素的最大覆盖范围(下标)
int nextCover=0; //记录下一步(注意是下一步)的最大覆盖范围(下标)
for(int i=0;i<nums.size();++i)
{//遍历数组,计算每个元素的最大覆盖范围,并check何时能跳到最后一个元素
nextCover=max(nums[i]+i,nextCover); //更新下一步最大覆盖范围下标
if(i==curCover)
{//只有在移动下标跳到当前元素的最大覆盖范围时(必然没到最后一个元素,因为break)
res++;
curCover=nextCover; //增加一步的时候更新当前元素的最大覆盖范围
if(curCover>=nums.size()-1)
break;//已经跳跃到最后一个元素,退出循环
}
}
return res;
}