C++算法 —— 贪心(3)

news2024/11/17 7:19:24

文章目录

  • 1、买卖股票的最佳时机
  • 2、买卖股票的最佳时机Ⅱ
  • 3、K次取反后最大化的数组和
  • 4、按身高排序
  • 5、优势洗牌
  • 6、最长回文串
  • 7、增减字符串匹配


1、买卖股票的最佳时机

121. 买卖股票的最佳时机

在这里插入图片描述
这里最容易想到的就是暴力枚举,两层for循环,i = 0, j = i + 1开始,但是这样是O(n ^ 2)的时间复杂度,即使倒过来,选定一个值,找到这个值前面的一堆数字中的最小值,一减就能找到最大利润,但是没解决本质。不妨想一下,从第二个数开始往后走。每一次都找前面一堆数字的最小值,但后面要找的其实已经包含前面要找的了,也就是找第7个数字之前的最小值,一大部分已经在找第6个数字之前的最小值时找过了,只要把这个最小值和第6个数字一比较,谁小,谁就是找第7个数字之前的最小值,这样,算法就是O(N)了。

    int maxProfit(vector<int>& prices) {
        int res = 0;
        for(int i = 0, prev = INT_MAX; i < prices.size(); ++i)
        {
            res = max(res, prices[i] - prev);//先更新结果是因为如果先更新最小值,那么结果就没法计算了
            prev = min(prev, prices[i]);
        }
        return res;
    }

2、买卖股票的最佳时机Ⅱ

122. 买卖股票的最佳时机 II

在这里插入图片描述
根据这个图,可以画一个折线图,每天的价格就是一个点,连接起来所有点。思路就是每次选一个点,都找到从这个点开始持续递增后的点,如果价格出现减少或不变,那就停止,这样每个增长趋势内可得到的最大利润都被算进来了,就能得到最大利润。

为了找到严格递增过程中最大的点,可以用双指针来控制。另一个方法是把每段交易变成一天一天,这个思路是只要第二天的数字比第一天大,那就加上第二天的数字。

        //双指针
        int ret = 0, n = prices.size();
        for(int i = 0; i < n; ++i)
        {
            int j = i;
            while(j + 1 < n && prices[j + 1] > prices[j]) ++j;
            ret += prices[j] - prices[i];
            i = j;
        }
        return ret;
        //拆分
        int ret = 0;
        for(int i = 1; i < prices.size(); ++i)
        {
            if(prices[i] > prices[i - 1])
                ret += prices[i] - prices[i - 1];
        }
        return ret;

3、K次取反后最大化的数组和

1005. K 次取反后最大化的数组和

在这里插入图片描述
理解这道题后会发现,应当先对最小的负数取反,才能得到最大和。从负数开始,从小到大,一个个取反。假设m是负数个数,m > k,那就把前k小的负数转化成正数;m == k,把所有负数全部转化为正数;m < k,先把所有负数都取反,剩余的次数k - m,如果它是偶数,那么就无影响,可以只对一个数字取反偶次数,那么这个数不变,如果是k - m是奇数,那就得把现有正数(因为已经取反了所有负数)中最小的那个数取反奇次数,就可以拿到最大数组和了。

    int largestSumAfterKNegations(vector<int>& nums, int k) {
        int m = 0, minElem = INT_MAX, n = nums.size();
        for(auto x : nums)
        {
            if(x < 0) m++;
            minElem = min(minElem, abs(x));
        }
        int ret = 0;
        if(m > k)
        {
            sort(nums.begin(), nums.end());
            for(int i = 0; i < k; ++i)
            {
                ret += -nums[i];
            }
            for(int i = k; i < n; ++i)
            {
                ret += nums[i];
            }
        }
        else
        {
            for(auto x: nums) ret += abs(x);
            if((k - m) % 2)
            {
                ret -= minElem * 2;
            }
        }
        return ret;
    }

4、按身高排序

2418. 按身高排序

在这里插入图片描述
我们可以创建一个新数组pair<int, string>这样名字和数字都在一起,对这个数组排序就行。

解法二是利用哈希表存映射关系。对身高数组排序,根据结果在哈希表里找名字即可。

以上两种思路类似,这里走一个不同的思路,虽然要排序,但不是真正的排序,对其中的元素不做手脚,但要能按照给出最终的顺序对应的元素。这里创建一个下标数组,只对下标数组排序,根据下标数组排序后的结果,找到原数组的信息。

    vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
        int n = names.size();
        vector<int> index(n);
        for(int i = 0; i < n; ++i)
        {
            index[i] = i;
        }
        sort(index.begin(), index.end(), [&](int i, int j)
        {
            return heights[i] > heights[j];
        });
        vector<string> ret;
        for(auto i : index)
        {
            ret.push_back(names[i]);
        }
        return ret;
    }

5、优势洗牌

870. 优势洗牌

在这里插入图片描述
这道题的意思是给了两个数组,返回一个最终的数组,比如例1,
2 7 11 15
1 10 4 11
第一个位置可以放2,比1,第二个位置可以放11,比10大,第三个可以放15,比4大,但这样第四个位置就放不了,所以这样优势不是最大化,第三个位置放7,第四个位置可以放15,这样优势就最大化了。

这道题可以用田忌赛马的思路,即,如果比不过,就放到另一个数组最大的那个对应的位置,如果能比过,那就直接比。在这之前,先排序一遍。

按照这个思路,看例2,我们会得到[12, 24, 32, 8]这个答案,和示例不一样,这是因为,我们是按照排序后的数组去做的结果,这个结果还需要对应上原先数组,所以还得改一下顺序,才是最终结果。

为此,要和上一个题一样,用下标数组来做。

    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        //排序
        sort(nums1.begin(), nums1.end());
        vector<int> index2(n);
        for(int i = 0; i < n; ++i) index2[i] = i;
        sort(index2.begin(), index2.end(), [&](int i, int j)
        {
            return nums2[i] < nums2[j];
        });

        //田忌赛马
        vector<int> ret(n);
        int left = 0, right = n - 1;
        for(auto x : nums1)
        {
            if(x > nums2[index2[left]]) ret[index2[left++]] = x;
            else ret[index2[right--]] = x;
        }
        return ret;
    }

6、最长回文串

409. 最长回文串

在这里插入图片描述
按照题目,回文串的长度是偶数或者奇数,从中间切一刀,两边都一样,中间切开的那个位置没有元素或者只有一个元素。所以我们可以这样想,一个字符串中可能出现的所有字符,记录下每个字符出现的次数,如果次数为偶数,就可以两边都放,那就是直接加上这个数字;如果是奇数,就-1,然后两边都放。所有次数可能不止有一个奇数,但奇数的个数不用担心,按照上面的做法,偶数就直接加,奇数就-1加上,算出来的长度如果等于原字符串长度,说明都是偶数,那就不用继续处理,直接返回;如果小于原字符串,说明出现了奇数,那么就+1,再返回。

    int longestPalindrome(string s) {
        int hash[127] = {0};
        for(char ch : s) hash[ch]++;
        int ret = 0;
        for(int x : hash)
        {
            ret += x / 2 * 2;//这样奇数偶数都能计算
        }
        return ret < s.size() ? ret + 1 : ret;
    }

7、增减字符串匹配

942. 增减字符串匹配

在这里插入图片描述
题目的意思就是给定一个字符串,比如IDI,那就增减增,从0123四个数字中选择来组成数组。

这道题体现的贪心是,为了符合字符串展现的规则,遇到I时,应当选择当前最小的那个数,遇到D时,选择当前最大的那个数。

    vector<int> diStringMatch(string s) {
        int left = 0, right = s.size();
        vector<int> res;
        for(auto ch : s)
        {
            if(ch == 'I') res.push_back(left++);
            else res.push_back(right--);
        }
        res.push_back(left);
        return res;
    }

结束。

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

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

相关文章

TFA-Net

TFA SCA means ‘Self-Context Aggregation’ 作者未提供代码

JVM中如何实现垃圾收集

Java虚拟机&#xff08;JVM&#xff09;使用垃圾收集器&#xff08;Garbage Collector&#xff09;来管理内存&#xff0c;清理不再使用的对象以释放内存空间。垃圾收集的主要目标是自动化内存管理&#xff0c;使开发人员无需显式地释放不再使用的内存&#xff0c;从而降低了内…

EFAK-v3.0.1版部署与使用

一、前言 EFAK&#xff08;(Eagle For Apache Kafka&#xff0c;以前称为Kafka Eagle&#xff09;用于在使用 Topic 的情况下监控 Kafka 集群。包含Offset 的产生、Lag的变化、Partition的分布、Owner、Topic的创建以及修改的时间等信息。 二、环境&安装包 官方下载连接E…

使用python 实现华为设备的SFTP文件传输

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址位172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;通过SFTP实现简单的上传下载操作。 实验拓扑&#xff1a; 实验步骤&#xff1a; 步骤1&#xff1a;将本地电脑和ensp的设备进行桥接&#xff…

华为云之SFS弹性文件服务使用体验

华为云之SFS弹性文件服务使用体验 一、本次实践介绍1.1 实践环境简介1.2 本次实践目的 二、SFS弹性文件服务介绍2.1 SFS弹性文件服务简介2.2 SFS弹性文件服务特点 三、购买ECS弹性云服务器3.1 购买ECS弹性云服务器3.2 查看ECS弹性云服务器状态3.3 远程连接ECS3.4 检查操作系统版…

线程信息分析,生产环境问题

现象&#xff1a; 应用服务器启动不了 产生原因&#xff1a; 最近升级了&#xff0c;将单线程查询数据变成了多线程查询数据。 分析&#xff1a; 推测一、sql 查询时间太慢导致 排查sql 后发现&#xff0c;不是这个原因 取回线程启动过程的线程信息 发现线程死锁了&…

无线通信:基于深度强化学习

这里写自定义目录标题 异构蜂窝网络&#xff1a;用户关联和信道分配a stochastic gameMulti-Agent Q-Learning MethodMulti-Agent dueling double DQN Algorithm 分布式动态下行链路波束成形Limited-Information Exchange ProtocolDistributedDRL-Based DTDE Scheme for DDBCDi…

每日一题:LeetCode-102.二叉树的层序遍历

每日一题系列&#xff08;day 03&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

使用Python对CSI相位进行矫正,并进行图像调整

一、前言 我记得我是最早将《MatLab对CSI的相位进行矫正》代码上传至网上的&#xff0c;后面陆续有人进行抄袭&#xff0c;不得已把一些细节和代码进行隐藏。今天整理之前Python代码的时候&#xff0c;发现一些不规范的问题&#xff0c;所以写了这篇博客。 二、使用Python对C…

大数据基础设施搭建 - Hive

文章目录 一、上传压缩包二、解压压缩包三、配置环境变量四、初始化元数据库4.1 配置MySQL地址4.2 拷贝MySQL驱动4.3 初始化元数据库4.3.1 创建数据库4.3.2 初始化元数据库 五、启动元数据服务metastore5.1 修改配置文件5.2 启动/关闭metastore服务 六、启动hiveserver2服务6.1…

手动实现 git 的 git diff 功能

这是 git diff 后的效果&#xff0c;感觉挺简单的&#xff0c;不就是 比较新旧版本&#xff0c;新增了就用 "" 显示新加一行&#xff0c;删除了就用 "-" 显示删除一行&#xff0c;修改了一行就用 "-"、"" 显示将旧版本中的该行干掉了并…

C#FlaUI.UIA实现发送微信消息原理

一 准备 .NetFramework 4.8 FlaUI.UIA3 4.0.0 FlaUInspect V1.3.0 1下载FlaUInspect https://github.com/FlaUI/FlaUInspect FlaUInspect V1.3.0 百度网盘下载 2 NuGet 引用 flaUI.UIA3 4.0.0 二代码部分 1 引用FlaUI using FlaUI.Core; using FlaUI.Core.Automatio…

深度学习基于Python+TensorFlow+Django的水果识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介简介技术组合系统功能使用流程 二、功能三、系统四. 总结 一项目简介 # 深度学习基于PythonTensorFlowDjango的水果识别系统介绍 简介 该水果识别系统基于…

比较2个点的3种结构在不规则平面上的占比

2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 3 3 3 x 3 3 2 2 2 1 2 2 2 2 2 1 2 2 在平面上有一个点x&#xff0c;再增加一个点,11的操作把平面分成了3部分2a1&#xff0c;2a2&#xff0c;2a3&#xff0c;3部分的比值是 2a1 2a2 2a3 5 25 …

单词接龙00

题目链接 单词接龙 题目描述 注意点 1 < beginWord.length < 10endWord.length beginWord.lengthwordList[i].length beginWord.lengthbeginWord、endWord 和 wordList[i] 由小写英文字母组成wordList 中的所有字符串 互不相同 解答思路 从beginWord开始&#xff…

最新版灵沐V3.3微信资源类小程序源码支持流量主

源码简介 最新版灵沐V3.3微信资源类小程序源码支持流量主&#xff0c;一套不错的流量主变现资源下载小程序&#xff0c;它支持在微信、QQ和抖音平台上运行。这次更新主要集中在全局UI设计的升级&#xff0c;并依然注重资源下载和激励视频变现的功能。另外&#xff0c;还新增了…

智慧楼宇可视化视频综合管理系统,助力楼宇高效安全运行

随着互联网技术的进步和发展&#xff0c;智能化的楼宇建设也逐步成为人们选择办公场所是否方便的一个重要衡量因素。在智能化楼宇中&#xff0c;安全管理也是重要的一个模块。得益于互联网新兴技术的进步&#xff0c;安防视频监控技术也得到了快速发展并应用在楼宇的安全管理中…

羊大师:强健身体是成功的关键

健康是一项无价的财富&#xff0c;拥有强健的身体是实现人生目标的关键。而如何保持健康并拥有一个强健的身体呢&#xff1f;下面就为大家分享一些有效的健身方法和建议&#xff0c;帮助您达到健美身材的目标。 良好的饮食习惯是形成强健身体的基石。我们要摄入足够的营养物质…

uniapp开发的微信小程序进行代码质量控制,分包+压缩js+组件按需注入等

小程序代码分包的操作请看另外一篇文章&#xff1a;uniapp分包优化&#xff0c;包括分包路由跳转规则-CSDN博客 JS文件压缩&#xff1a;在工具「详情」-「本地设置」中开启「上传代码时自动压缩脚本文件」的设置 代码包&#xff1a;组件 > 启用组件按需注入解决办法 在小程…

如何选择ZK-friendly 哈希函数?

1. 引言 在What’s the deal with hash functions in Zero Knowledge?中&#xff0c;研究了哈希函数对ZKP场景的用途。当前有各种ZK-friendly 哈希函数设计&#xff0c;各有优缺点&#xff0c;且针对不同的性能维度进行了优化&#xff0c;如&#xff1a; MiMCGMiMCPoseidonP…