Hot100之贪心算法

news/2025/2/3 11:50:23 标签: 贪心算法, 算法, leetcode, 数据结构

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;//假设我们第一次能跳跃到的最远位置为end

while(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;

    }
}

 


http://www.niftyadmin.cn/n/5840761.html

相关文章

题单:选择排序

题目描述 给定 n 个元素的数组&#xff0c;请使用选择排序对其进行排序&#xff08;升序&#xff09;。 &#xff08;如果有多个相同的最小值&#xff0c;以下标最大的为准&#xff09; 输入格式 两行&#xff0c;第一行为一个整数 n&#xff0c;表示元素的个数。 第二行 …

LeetCode:474.一和零

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;474.一和零 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度…

语音识别播报人工智能分类垃圾桶(论文+源码)

2.1 需求分析 本次语音识别播报人工智能分类垃圾桶&#xff0c;设计功能要求如下∶ 1、具有四种垃圾桶&#xff0c;分别为用来回收厨余垃圾&#xff0c;有害垃圾&#xff0c;可回收垃圾&#xff0c;其他垃圾。 2、当用户语音说出“旧报纸”&#xff0c;“剩菜”等特定词语时…

机器学习--概览

一、机器学习基础概念 1. 定义 机器学习&#xff08;Machine Learning, ML&#xff09;&#xff1a;通过算法让计算机从数据中自动学习规律&#xff0c;并利用学习到的模型进行预测或决策&#xff0c;而无需显式编程。 2. 与编程的区别 传统编程机器学习输入&#xff1a;规…

Ubuntu 下 nginx-1.24.0 源码分析 ngx_debug_init();

目录 ngx_debug_init() 函数&#xff1a; NGX_LINUX 的定义&#xff1a; ngx_debug_init() 函数&#xff1a; ngx_debug_init() 函数定义在 src\os\unix 目录下的 ngx_linux_config.h 中 #define ngx_debug_init() 也就是说这个环境下的 main 函数中的 ngx_debug_init() 这…

K8S集群部署--亲测好用

最近在自学K8S&#xff0c;花了三天最后终于成功部署一套K8S Cluster集群&#xff08;masternode1node2&#xff09; 在这里先分享一下具体的步骤&#xff0c;后续再更新其他的内容&#xff1a;例如部署期间遇到的问题及其解决办法。 部署步骤是英文写的&#xff0c;最近想练…

【Rust自学】19.2. 高级trait:关联类型、默认泛型参数和运算符重载、完全限定语法、supertrait和newtype

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 19.2.1. 在trait定义中使用关联类型来指定占位类型 我们首先在第10章的10.3. trait Pt.1&a…

用结构加法3ax+1预测第4点的分布

有1个点在19*19的平面上在某种力的作用下运动&#xff0c;轨迹为 共移动了90步&#xff0c;按照&#xff08;0&#xff0c;1&#xff0c;2&#xff0c;3&#xff09;&#xff0c;&#xff08;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff09;&#xff0c;…&#xff0c;&…