欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > Hot100之贪心算法

Hot100之贪心算法

2025/2/8 3:43:16 来源:https://blog.csdn.net/LUCIAZZZ/article/details/145416636  浏览:    关键词:Hot100之贪心算法

121买股票的最佳时机

题目

思路解析

有两种解法,DP和维护第i天最小值

维护第i天前的最小值

从左到右枚举卖出价格 prices[i

那么要想获得最大利润,我们需要知道第 i 天之前股票价格的最小值是什么

也就是从 prices[0] 到 prices[i−1] 的最小值,把它作为买入价格,这可以用一个变量 minPrice 维护。

请注意,minPrice 维护的是 prices[i] 左侧元素的最小值。

由于只能买卖一次,所以在遍历中,维护 prices[i]−minPrice 的最大值,就是答案。


DP

我们弄一个二维的dp【】数组

dp【i】【0】指的是下标为i这天结束的时候,持股,手上拥有的最大现金

dp【i】【1】指的是下标为i这天结束的时候,不持股,手上拥有的最大现金

所以我们一开始初始化的时候是这样初始化的

第一天买股了和第一天卖股了

//初始化
dp[0][0]=-prices[0];
dp[0][1]=0;

有了这个逻辑,所以我们的dp逻辑就出来了

买股我们就减去当天的price

卖股我们就加上当天的price

for(int i=1;i<prices.length;i++)
{// dp[i][0] 下标为 i 这天结束的时候,持股,手上拥有的最大现金数// dp[i][1] 下标为 i 这天结束的时候,不持股,手上拥有的最大现金数//可以看成如果我们今天买股消耗的钱更少,我们就要选消耗钱更少的dp[i][0]=Math.max(dp[i-1][0],0-prices[i]);//保证第i天及以前卖股的最大值dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);}

dp【i】【0】存储第i天以及第i天之前,我们买股票的消耗钱最小值

dp【i】【1】存储第i天以及第i天之前,我们卖股票的最大值

从前往后递推

我们就能记录第i天以及第i天之前,我们遇到的最低价钱的股票,和卖股票能钻到钱的最大值


代码

维护第i天前的最小值
class Solution {public int maxProfit(int[] prices) {int ans = 0;int minPrice = prices[0];for (int p : prices) {ans = Math.max(ans, p - minPrice);minPrice = Math.min(minPrice, p);}return ans;}
}

DP
class Solution {public int maxProfit(int[] prices) {int dp[][]=new int[prices.length][2];
//初始化
dp[0][0]=-prices[0];
dp[0][1]=0;for(int i=1;i<prices.length;i++)
{// dp[i][0] 下标为 i 这天结束的时候,持股,手上拥有的最大现金数// dp[i][1] 下标为 i 这天结束的时候,不持股,手上拥有的最大现金数//可以看成如果我们今天买股消耗的钱更少,我们就要选消耗钱更少的dp[i][0]=Math.max(dp[i-1][0],0-prices[i]);//保证第i天及以前卖股的最大值dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);}return Math.max(dp[prices.length-1][0],dp[prices.length-1][1]);}
}

55跳跃游戏 

题目

是否能跳跃到最后一个位置

思路解析

我们for循环从左往右遍历

每次都找能跳跃到的最大下标

然后我们还有个i<=most,意思是我们的最远距离可以跳跃到或者大于i这个距离

我们的下标才能继续往下判断是否能继续跳跃

跳不到的话就不做行为,相当于结束了

如果遍历完之后,我们的most还是小于数组长度,那说明跳跃不到最后一个节点

代码

class Solution {public boolean canJump(int[] nums) {int length=nums.length;
int most=0;for(int i=0;i<length;i++)
{
if(i<=most)
{most=Math.max(most, i + nums[i]);
}if(most>=length-1)
return true;}return false;}
}

45跳跃游戏2 

题目

跳跃到最后一个位置的最小跳跃次数

思路解析

我们要找到跳跃到的最远位置时能走的最短距离

首先我们要关注不能漏跳的问题和一些小点

例如【2,3,0,1,4】

我们肯定是 2,3,4这样跳到最后

而不是2,0这样子跳

也不是2,3,1,4这样子跳

首先我们不能漏跳

其次我们要跳的次数最少

所以我们有个start节点记录每次跳跃的开始位置,有个end节点,记录每次跳跃时能跳跃到的最远位置

我们for循环

//找到我们能跳跃到的最远位置end
for(int i=start;i<end;i++)
{maxpos=Math.max(maxpos,i+nums[i]);
}

i为起点,end-1为终点,然后for循环遍历,更新我们的能跳到的最远处

这样子就不会漏节点了

代码

class Solution {public int jump(int[] nums) {int ans=0;
int start=0;
int end=1;//假设我们第一次能跳跃到的最远位置为endwhile(end<nums.length)
{int maxpos=0;//找到我们能跳跃到的最远位置end
for(int i=start;i<end;i++)
{maxpos=Math.max(maxpos,i+nums[i]);
}//start变成上一次能跳跃到的最远位置
start=end;
//end变成for循环中我们能找到的新的能跳到的最远位置
end=maxpos+1;ans++;}
return ans;}
}

 


763划分字母区间

题目

思路解析

存字母的最远下标

//存对应字母的最远下标
for(int i=0;i<s.length();i++)
{arr[Crr[i]-'a']=i;}

我们遍历的时候不断更新当前遍历的字符串中字符的最远下标

然后当最远下标和当前下标匹配时,说明这个点就是最远的点了,我们收集答案

//遍历的时候,记录遍历的这段字母中的最远下标
right=Math.max(right,arr[Crr[i]-'a']);//当匹配到字符串中字母的最远下标,我们就记录个数
if(right==i)
{list.add(right-left);
left=right;}

代码

class Solution {public List<Integer> partitionLabels(String s) {List<Integer> list=new LinkedList<>();int [] arr=new int[26];
char [] Crr=s.toCharArray();
int right=0;
int left=-1;//存对应字母的最远下标
for(int i=0;i<s.length();i++)
{arr[Crr[i]-'a']=i;}for(int i=0;i<s.length();i++)
{//遍历的时候,记录遍历的这段字母中的最远下标
right=Math.max(right,arr[Crr[i]-'a']);//当匹配到字符串中字母的最远下标,我们就记录个数
if(right==i)
{list.add(right-left);
left=right;}}return list;}
}

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com