LeetCode 热题 100 | 贪心算法

news2024/11/18 18:32:53

目录

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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Day5-Hive的结构和优化、数据文件存储格式

Hive 窗口函数 案例 需求&#xff1a;连续三天登陆的用户数据 步骤&#xff1a; -- 建表 create table logins (username string,log_date string ) row format delimited fields terminated by ; -- 加载数据 load data local inpath /opt/hive_data/login into table log…

armlinux-外部中断

s3c2440的中断框图 如果我们单纯配置一个按键的外部中断&#xff0c;就不存在子中断与优先级的问题。 由于是按键的外部中断&#xff0c;通过引脚的高低电平来触发。所以我们要先配置引脚的功能。 我们使用按键1&#xff0c;终端源为EINT8&#xff0c;对应引脚GPG0 通过用户手…

Stable diffusion 加载扩展列表报错解决方法

项目场景&#xff1a; 在使用Stable diffusion webui时&#xff0c;使用扩展列表出现错误 问题描述 点击loadfrom后&#xff0c;出现加载扩展列表报错 原因分析&#xff1a; 下载的扩展的时候&#xff0c;都是github 的url&#xff0c;需要科学上网&#xff0c;如果不能科学…

深澜计费管理系统 任意文件读取漏洞复现

0x01 产品简介 深澜计费管理系统是是一套完善的领先的具有复杂生物型特征的弹性认证计费系统。系统主要由 AAA 认证计费平台、系统运营维护管理平台、用户及策略管理平台、用户自助服务平台、智能客户端模块、消息推送模块、数据统计模块组成。目前在全球为超过 2500 家客户提…

MicroPython 树莓派 RP2 入门教程

系列文章目录 前言 Raspberry Pi Pico 开发板&#xff08;图片来源&#xff1a;Raspberry Pi 基金会&#xff09;。 以下是 Raspberry Pi RP2xxx 板的快速参考资料。如果您是第一次使用该开发板&#xff0c;了解微控制器的概况可能会对您有所帮助&#xff1a; 一、关于 RP2xxx…

【项目实战】——商品管理的制作完整代码

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

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

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

Vue项目登录页实现获取短信验证码的功能

之前我们写过不需要调后端接口就获取验证码的方法,具体看《无需后端接口,用原生js轻松实现验证码》这个文章。现在我们管理后台有个需求,就是登录页面需要获取验证码,用户可以输入验证码后进行登录。效果如下,当我点击获取验证码后能获取短信验证码: 这里在用户点击获取…

Cortex-M7 异常处理与返回

1 前言 当CM3开始响应一个中断时&#xff0c;会在它小小的体内奔涌起三股暗流&#xff1a;  入栈&#xff1a; 把8个寄存器的值压入栈;  取向量&#xff1a;从向量表中找出对应的服务程序入口地址;  选择堆栈指针MSP/PSP&#xff0c;更新堆栈指针…

LeetCode 19.删除链表的倒数第N个结点

给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 示例 3&#x…

Leetcode 39.组合总和

题目 思路 1.确定递归函数的返回值及参数&#xff1a; 返回值是void,参数这里还是先设定两个全局变量。一个是path存放符合条件单一结果。如&#xff1a;&#xff08;1&#xff0c;2&#xff09;。一个是result&#xff0c;是所有path的集合[(1,2),(1,3)…]。 此外再设定一个…

前端学习之DOM编程-docmument对象、操作DOM对像内容、操作DOM对象属性方式、操作DOM对象的样式

docmument对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>document对象</title> </head> <body><div id"container" nameparent><ul name"parent&qu…

计算机系统结构速成,期末和自考必备

【拯救者】计算机系统结构速成(期末自考)均可用 1️⃣先讲每章对应的基础 2️⃣接着会讲对应的题目巩固 &#x1f357;提供文档下载 这里讲的是【 &#x1f337;速成&#x1f337; 速成&#x1f337; 速成】版本&#xff0c;按课本章节来&#xff0c; 抽取重点&#xff0c;翻…

数据分析——数据规范化

数据规范化是数据分析中的一个重要步骤&#xff0c;其目的在于确保数据的一致性和可比性&#xff0c;提高数据质量和分析结果的准确性。以下是一些数据规范化的常见方法和技术&#xff1a; 数据清洗&#xff1a;此步骤主要清除数据中的重复项、空格、格式错误等&#xff0c;确…

Transformer Based Multi-view Network for Mammographic Image Classification

“C-Tk” means “Classification Token” 辅助信息 作者未提供代码

【python从入门到精通】-- 第四战:语句汇总

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

C++:函数重载和引用

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习C&#xff1a;函数重载和引用&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 函数重载1.函数重载的概念为什么C支持函数重载 引用引用的概念引…

C++中发送HTTP请求的方式

一&#xff0c;简介 使用C编程发送HTTP请求通常需要使用第三方的HTTP库或框架。在C中&#xff0c;有几个受欢迎的HTTP库可供选择&#xff0c;例如Curl、Boost.Beast和cpp-httplib。另外&#xff0c;也可以自己实现socket来发送http请求 二、使用Curl库发送HTTP请求 1. 确认当…

day60 动态规划part17

这两题看了自己写的笔记还不懂的话&#xff0c;看看这个up的思路就行&#xff1a; https://space.bilibili.com/111062940/search/video?keyword%E5%9B%9E%E6%96%87 647. 回文子串 中等 提示 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回…

微带线特性阻抗快速计算---根据介质板参数和特性阻抗得到线宽(Matlab代码)

微带线特性阻抗快速计算—根据介质板参数和特性阻抗得到线宽&#xff08;Matlab代码&#xff09; 参考&#xff1a;https://blog.csdn.net/weixin_45811090/article/details/130045689 《射频电路理论与设计》第2版 黄玉兰著 《射频电路设计——理论与应用》第二版 Reinhold L…