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

文章目录

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

结束。

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

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

相关文章

分布式链路追踪实战篇-日志库集成opentelemetry的思路

由上文分布式链路追踪入门篇-基础原理与快速应用可以知道分布式链路追踪的作用&#xff0c;但是距离应用到项目中&#xff0c;我们还需要对项目中一些关键组件进行opentelemetry的集成&#xff0c;例如日志库&#xff0c;ORM、http框架、rpc框架等。 一、日志库如何集成opentel…

设计模式-创建型模式-工厂方法模式

一、什么是工厂方法模式 工厂模式又称工厂方法模式&#xff0c;是一种创建型设计模式&#xff0c;其在父类中提供一个创建对象的方法&#xff0c; 允许子类决定实例化对象的类型。工厂方法模式是目标是定义一个创建产品对象的工厂接口&#xff0c;将实际创建工作推迟到子类中。…

美创联合浙江省农业农村厅斩获“IDC中国20大杰出安全项目”!

11月23日&#xff0c;由IDC主办&#xff0c;以“安全风险管控&#xff1a;新形势下的数据安全保护”为主题的2023全球CSO网络安全峰会&#xff08;中国站&#xff09;隆重召开。 会上&#xff0c;IDC “中国20大杰出安全项目&#xff08;CSO20&#xff09;” 重磅揭晓&#xff…

Linux中df命令使用

在Linux中&#xff0c;df命令用于显示磁盘空间的使用情况。它的基本语法如下&#xff1a; df [选项] [文件或目录]这个命令可以用来查看当前系统上各个磁盘分区的使用情况。如果没有指定文件或目录&#xff0c;则所有当前被挂载的文件系统的可用空间将被显示。 df命令的一些常…

手把手用GPT开发小程序全流程!就是这么easy~

大家好&#xff0c;我是五竹。 前段时间用GPT开发了一款小程序:GPT真牛批&#xff01;三天开发一个小程序&#xff0c;三天积累了2000的用户&#xff0c;上周末抽空又接入了流量主&#xff0c;感兴趣的同学可以围观一下。 今天就来带大家走一遍用GPT开发一款小程序的全过程&a…

手把手webpack搭建前端架子

这里以react为例> (一)初始化package.json package name: 你的项目名字叫啥 version: 版本号 description: 对项目的描述 entry point: 项目的入口文件&#xff08;一般你要用那…

【回眸】Tessy单元测试软件使用指南(一)安装篇

安装 在官网上下载安装包&#xff0c;安装完成后打开进入这个界面 注册申请license&#xff1a;在作为服务端的电脑上安装Tessy。安装完成后&#xff0c;启动Tessy会自动生成license服务器的注册码。&#xff08;注册码用于申请试用或永久的license文件&#xff09;这个对于我…

树莓派上使用Nginx通过内网穿透实现无公网IP访问内网本地站点

前言 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Nginx 的内存占用率非常低&#xff0c;可以在树莓派等资源受限的设备上运行。同时结合c…

NX二次开发UF_CSYS_set_wcs 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_set_wcs Defined in: uf_csys.h int UF_CSYS_set_wcs(tag_t csys_id ) overview 概述 Sets the work coordinate system to the prototype coordinate system whose tag y…

竞赛选题 题目:基于FP-Growth的新闻挖掘算法系统的设计与实现

文章目录 0 前言1 项目背景2 算法架构3 FP-Growth算法原理3.1 FP树3.2 算法过程3.3 算法实现3.3.1 构建FP树 3.4 从FP树中挖掘频繁项集 4 系统设计展示5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于FP-Growth的新闻挖掘算法系统的设计与实现…

【PDF.js】2023 最新 PDF.js 在 Vue3 中的使用

因为自己写业务要定制各种 pdf 预览情况&#xff08;可能&#xff09;&#xff0c;所以采用了 pdf.js 而不是各种第三方封装库&#xff0c;主要还是为了更好的自由度。 一、PDF.js 介绍 官方地址 中文文档 PDF.js 是一个使用 HTML5 构建的便携式文档格式查看器。 pdf.js 是社区…

【HuggingFace Transformer库学习笔记】基础组件学习:pipeline

一、Transformer基础知识 pip install transformers datasets evaluate peft accelerate gradio optimum sentencepiece pip install jupyterlab scikit-learn pandas matplotlib tensorboard nltk rouge在host文件里添加途中信息&#xff0c;可以避免运行代码下载模型时候报错…

vue中下载文件后无法打开的坑

今天在项目开发的时候临时要添加个导出功能我就写了一份请求加导出得代码&#xff0c; 代码&#xff1a; //导出按钮放开exportDutySummarizing (dataRangeInfo) {const params {departmentName: dataRangeInfo.name,departmentQode: dataRangeInfo.qode}//拼接所需得urlcons…

Tomcat注册为服务后,如何配置Tomcat内存大小

前提条件&#xff1a;tomcat已经注册为服务。 1.winR,输入regedit打开注册表 2.找到Tomcat注册表路径&#xff1a; HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\Tomcat80603.找到jvm内存配置路径&#xff1a; HKEY_LOCAL_MACHINE\SOFTW…

Redis高可用之主从复制及哨兵模式

一、Redis的主从复制 1.1 Redis主从复制定义 主从复制是redis实现高可用的基础&#xff0c;哨兵模式和集群都是在主从复制的基础之上实现高可用&#xff1b; 主从复制实现数据的多级备份&#xff0c;以及读写分离(主服务器负责写&#xff0c;从服务器只能读) 1.2 主从复制流…

Windows从源码构建tensorflow

由一开始的在线编译&#xff0c;到后面的离线编译&#xff0c;一路踩坑无数。在此记录一下参考过的文章&#xff0c;有时间整理一下踩坑记录。 一、环境配置 在tensorflow官网上有版本对应关系 win10 bazel 3.1.0 msys2 tensorflow2.3.0 python3.5-3.8 MSVC2019 protobuf3.9.…

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

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

Java二级医院区域HIS信息管理系统源码(SaaS服务)

一个好的HIS系统&#xff0c;要具有开放性&#xff0c;便于扩展升级&#xff0c;增加新的功能模块&#xff0c;支撑好医院的业务的拓展&#xff0c;而且可以反过来给医院赋能&#xff0c;最终向更多的患者提供更好的服务。 系统采用前后端分离架构&#xff0c;前端由Angular、J…

首先啊骚年们我们必须先了解网络安全这个行业究竟是干啥的。

导 读 近年来&#xff0c;人工智能、5G、量子信息技术、工业互联网、大数据、云计算、物联网、虚拟现实、区块链等具有颠覆性的战略性新技术突飞猛进&#xff0c;但伴随着互联网技术的发展&#xff0c;网络安全问题也日趋多样化&#xff0c;甚至严重威胁到国家、企业&#xff…

【正点原子STM32连载】 第六十章 串口IAP实验(Julia分形)实验 摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子APM32F407最小系统板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html## 第六十…