LeetCode 热题 100 | 贪心算法

目录

1  121. 买卖股票的最佳时机

2  55. 跳跃游戏

3  45. 跳跃游戏 II

4  763. 划分字母区间


菜鸟做题,语言是 C++

1  121. 买卖股票的最佳时机

解题思路:

  • 维护一个变量 max_price
  • max_price 用于存储排在 i 天之后的股票最高价格
  • 第 i 天的最高利润 = max_price - 第 i 天的股票价格

思路说明:

假设股票价格数组为 [7,1,5,3,6,4],从后往前遍历数组以计算 max_price,如下图所示。

1)如果第 i 天的股票价格低于 max_price,则

  • 第 i 天的最高利润 = max_price - 第 i 天的股票价格
  • 需要更新 profit
  • 不需要更新 max_price

2)如果第 i 天的股票价格高于 max_price,则

  • 第 i 天的最高利润 = 0
  • 不需要更新 profit
  • 需要更新 max_price

在如下代码中,我用的是变量 ans 代表 profit 的含义。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        int ans = 0, max_price = 0;

        for (int i = n - 1; i >= 0; --i) {
            if (prices[i] > max_price) {
                max_price = prices[i];
            } else {
                ans = max(ans, max_price - prices[i]);
            }
        }

        return ans;
    }
};

2  55. 跳跃游戏

解题思路:

  • 遍历 nums 数组
  • 不断更新最远距离 maxDistance
  • 如果 maxDistance >= nums.size() - 1,则返回 true

思路说明图:

  1. 遍历第 0 个元素,maxDistance = 2
  2. 遍历第 1 个元素,maxDistance = 1 + 3 = 4
  3. 遍历第 2 个元素,maxDistance = 4(> 2 + 1)
  4. 以此类推
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int maxDistance = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (i <= maxDistance) {
                maxDistance = max(i + nums[i], maxDistance);
            }
        }
        return maxDistance >= nums.size() - 1;
    }
};

3  45. 跳跃游戏 II

解题思路:

  • 仍然是遍历 nums 数组,每次更新 maxDistance 范围
  • 针对在同一次更新后被包含进去的位置,算作一次跳跃

思路说明图:

将 maxDistance 初始化为 0,被包含进去的 0 号位置,属于第一次跳跃(count = 0)。根据 0 号位置更新 maxDistance 为 2,被包含进去的 1、2 号位置,属于第二次跳跃(count = 1)。根据 1、2 号位置更新 maxDistance 为 4,被包含进去的 3、4 号位置,属于第三次跳跃(count = 2)。

如果更新 maxDistance 后发现 maxDistance >= nums.size() - 1,则返回 count + 1 即可。为什么是 count + 1?因为目前只是能够跳跃到达 nums.size() - 1,但还没有跳。

class Solution {
public:
    int jump(vector<int>& nums) {
        int maxDistance = 0;
        int pos = 0, count = 0;

        if (pos >= nums.size() - 1)
            return 0;

        while (pos < nums.size()) {
            int temp = maxDistance;
            while (pos <= temp) {
                maxDistance = max(maxDistance, pos + nums[pos]);
                if (maxDistance >= nums.size() - 1) {
                    return count + 1;
                }
                ++pos;
            }
            ++count;
        }

        return count;
    }
};

4  763. 划分字母区间

解题思路:

  • 遍历字符串 s,记录每个字母的最后出现位置
  • 设置 begin = 0,即从 0 号字母开始划分字符串
  • 根据每个字母的最后出现位置不断更新 end
  • 若当前位置 = end,则 begin ~ end 之间是一个子串

思路说明图:

  • 图中的 B 代表 begin,即子串的开头;E 代表 end,即子串的结尾
  • 初始化 begin 为 0,初始化 E 为第一个字母的最后出现位置

我们需要保证的是 B 和 E 之间的所有字母不能横跨两个子串。换句话说,B 和 E 之间的 b 和 c 的最后出现位置不能超过 a 的最后出现位置 E 。如果超过了,我们需要更新 E 。

第一轮:首先访问 a,并且设置 E 为 a 的最后出现位置;接着访问 b,由于 b 的最后出现位置没有超过 E,因此不需要更新 E。以此类推访问到 c,由于 c 的最后出现位置没有超过 E,因此不需要更新 E 。最后指针 i 移动到 E,说明 B 和 E 之间的字母只会出现在该区间内,由此得到第一个子串。

第二轮:B 更新到 E 的后面一个位置,模仿第一轮的操作继续访问。

由于篇幅有限,因此图中省略了一些步骤,请自行脑补。

class Solution {
public:
    vector<int> partitionLabels(string s) {
        unordered_map<char, int> charEnd;
        for (int i = 0; i < s.size(); ++i) {
            charEnd[s[i]] = i;
        }

        vector<int> ans;
        int begin = 0, end = 0;
        for (int i = 0; i < s.size(); ++i) {
            end = max(end, charEnd[s[i]]);
            if (i == end) {
                ans.push_back(end - begin + 1);
                begin =  end + 1;
            }
        }

        return ans;
    }
};

上述代码用的是哈希表 charEnd 来存储字母的最后出现位置,换成 vector<int> 也行。

这样做会超出内存限制:

int subStrEnd = charEnd[s[0]];
while (begin < s.size()) {
    while (end <= subStrEnd) {
        subStrEnd = max(subStrEnd, charEnd[s[end]]);
        ++end;
    }
    ans.push_back(end - begin);
    begin = end;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/518821.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

地质地貌卫星影像集锦(三 矿产资源篇)

1. 元古代沉积岩的抬升 这个地区位于Leigh Creek中部&#xff0c;距离澳大利亚南部的阿德莱德约500km&#xff0c;弗林德斯山脉的北面是Gawler克拉通。弗林德斯山脉是由元古代沉积岩抬升后形成的块体&#xff0c;在其之下的是寒武纪的岩石&#xff0c;它座落在距阿德莱德北…

唐刘:关于产品质量的思考 - 我的基本认知

我在文章《 TiDB in 2023 - 一次简单的回顾 》 中提到了一个我一直以来面临的问题&#xff1a;每次 TiDB 发布新版本后&#xff0c;我如何能够非常自信地告诉客户&#xff0c;这个版本的质量很好&#xff0c;大家可以放心使用呢&#xff1f; 坦白地说&#xff0c; 这个问题并不…

[HackMyVM]靶场Deeper

难度:Easy kali:192.168.56.104 靶机:192.168.56.148 端口扫描 ┌──(root㉿kali2)-[~/Desktop] └─# nmap 192.168.56.148 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-05 19:55 CST Nmap scan report for 192.168.56.148 Host is up (0.00013s latency). N…

数据结构:详解【树和二叉树】

1. 树的概念及结构&#xff08;了解&#xff09; 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝…

智慧公厕升级为多功能城市智慧驿站,助力智慧城市发展

在现代城市的建设中&#xff0c;公共厕所作为基础必备的民生设施&#xff0c;一直是城市管理的重要组成部分。随着科技的不断发展&#xff0c;智慧公厕应运而生&#xff0c;成为了公共厕所信息化、数字化、智慧化的应用解决方案。而近年来&#xff0c;智慧公厕也进行了升级发展…

20240309web前端_第三周作业_教务系统页面

作业&#xff1a;教务系统页面 成果展示&#xff1a; 完整代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…

拥塞控制算法系列之:Swift-谷歌2020年SIGCOM-包级别端到端TIMELY拥塞控制算法

核心要点&#xff1a; 谷歌 2020 SIGCOM基于delay的AIMD拥塞拆分EC和FC&#xff0c;时延敏感场景优势分别计算EC和FC的wnd&#xff08;最核心&#xff09;保障吞吐和低延迟。Swift 因利用延迟的简单性和有效性而闻名包级别的论文&#xff1a;https://dl.acm.org/doi/pdf/10.11…

【保姆级讲解如何计算机视觉入门】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

江协STM32:对射式红外传感器计次和旋转编码器计次

对射式红外传感器计次 还是复制粘贴之前的文件 创建外部中断文件 然后写初始化函数 外部中断函数创建 这里写外部中断函数 看着这个图来配置 具体步骤就是&#xff1a; 第一步&#xff0c;配置RCC&#xff0c;把我们这里涉及的外设的时钟都打开&#xff0c;不打开时钟&#…

深入浅出 -- 系统架构之微服务中OpenFeign最佳实践

前面我们讲了一下 Ribbon 和 RestTemplate 实现服务端通信的方法&#xff0c;Ribbon 提供了客户端负载均衡&#xff0c;而 RestTemplate 则对 http 进行封装&#xff0c;简化了发送请求的流程&#xff0c;两者互相配合&#xff0c;构建了服务间的高可用通信。 但在使用后也会发…

c++的学习之路:12、vector(1)

这章主要是根据cplusplus中的文档进行使用Vector&#xff0c;文章末附上测试代码。 目录 一、什么是vector 二、vector的简单使用 三、代码 一、什么是vector 下图是cplusplus的简介&#xff0c;上面一共有六点&#xff0c;如下&#xff1a; 1、vector是表示可变大小数组…

Leetcode 216.组合总和III

题目 思路 题目说只使用数字1-9&#xff0c;是k个数的和 树的宽度是1-9&#xff0c;树的深度是k 1.确定递归函数的返回值及参数&#xff1a; 返回值是void,参数这里还是先设定两个全局变量。一个是path存放符合条件单一结果。如&#xff1a;&#xff08;1&#xff0c;2&…

VSCODE EIDE使用debug记录

用上vscode之后就感觉之前的keil不太爽了&#xff0c;找什么东西搜索都很麻烦&#xff0c;之前有写过eide的文章&#xff0c;想着能不能在eide里面就把debug也做了&#xff0c;发现真的可以&#xff0c;下面记录一下&#xff0c;主要是参考这个大佬的文章&#xff0c;非常感谢。…

微电网优化:基于肝癌算法(Liver Cancer algorithm, LCA)的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…

离线数仓(十)【ADS 层开发】

前言 剩下的 ADS 层主要就是写 SQL 了&#xff0c;就像我们之前练习的 HQL 题一样&#xff0c;不同的是这里的数据从哪张表读取&#xff08;DWD 还是 ADS 甚至个别表需要从 DIM 层读取&#xff09;需要我们自己来分析。 ADS 的建表语句和 MySQL 是对应的&#xff0c;我们到时候…

网络协议——HTTP协议

目录 ​编辑 一&#xff0c;HTTP协议基本认识 二&#xff0c;认识URL 三&#xff0c;http协议的格式 1&#xff0c;发送格式 2&#xff0c;回应格式 四&#xff0c;服务端代码 五&#xff0c;http报文细节 1&#xff0c;Post与Get方法 2&#xff0c;Content_lenth 3&…

OpenCV-python安装教程

先安装opencv-contrib-python pip install opencv-contrib-python 再换源安装opencv-python pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple 如果出现 使用这个&#xff0c;3.6环境下不能安装opencv的最新版本 pip install opencv-python4.5.5.62…

ST表(Segment Tree)

目录 1.概述 2.引入 3.ST表对引入的优化 1.概述 ST表是一种基于树形结构的数据结构&#xff0c;用于处理区间查询和更新操作。它通过预处理的方式将原始数据存储在树状结构中&#xff0c;以支持高效的区间查询。ST表的构建时间复杂度为O(nlogn)&#xff0c;其中n为原始数据…

算法——分治(快速排序)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享分治算法关于快速排序的专题 对于快速排序在我个人主页专栏 <排序> 有详细的介绍,此专题对快排进行了优化操作,并介绍了优化后的快排的几种运用 如果有不足的或者错误的请…

数组方法汇总

数组和链表类似&#xff0c;都是用双指针&#xff0c;但数组不需要额外的指针&#xff0c;可以使用索引来当作指针。&#xff08;链表的时候要注意&#xff0c;什么时候是移动的指针&#xff0c;什么时候是改变的节点&#xff09;删除有序数组中的重复项 注意&#xff0c;本题中…