贪心算法(二)

news/2024/12/18 12:38:00/

目录

一、最长递增子序列

二、递增的三元子序列

三、最长连续递增序列

四、买卖股票的最佳时机

五、买卖股票的最佳时机II


一、最长递增子序列

最长递增子序列

拿到这道题,我们最先想到的就是用动态规划的方法去解决它。使用动态规划的方法,我们只需要考虑元素能否接在他之前的某个元素后面,从而形成递增子序列。

而我们可以根据动态规划算法对其进行优化。我们并不需要关心这个递增子序列长什么样子,我们仅关心递增子序列的最后一个元素是什么。 

贪心策略: 

从前到后扫描每一个元素,当扫描第一个位置的元素时候,其实我们得到一个长度为1 的序列的最后一个位置的元素。如下图:

扫描到9的时候发现,9是接不到10后面的,所以9这个元素单独形成一个长度为1的序列,现在又找到一个长度为1的序列最后一个元素是9。此时贪心策略就来了,当我发现长度为1递增子序列有两个的时候,较大的就没有必要存了。 如下图:

扫描2的时候,2是接不到9后面的,所以2这个元素单独形成一个长度为1的序列,并且2小于9,所以不存9,存2。如下图:

扫描5的时候,我们其实有两种策略,第一种是让5单独形成一个长度为1的序列,第二种是让5拼到2的后面形成一个长度为2的序列。此时我们贪心选择第二种策略。因为要找最长递增子序列。如下图:

扫描到3的时候,3可以接在2的后面,但不能接在5的后面,所以递增序列长度为2的位置存较小的3。如下图:

扫描到7的时候,7可以接在2的后面,也可以接在3的后面,因为要找最长的递增序列,所以将7放在3的后面,形成长度为3的递增序列。如下图:

扫描到101的时候,101可以接在2的后面,也可以接在3的后面,也可以接在7的后面,因为要找最长的递增序列,所以将101放在7的后面,形成长度为4的递增序列。如下图:

扫描到18的时候,18可以接在2的后面,也可以接在3的后面,也可以接在7的后面,但无法接在101的后面,所以递增序列长度为4时,最后位置的元素存较小的18。如下图:

至此,所有的元素都已经扫描完毕了, 最终得到的最长递增子序列的长度是4。

我们在确定一个元素所在的位置的时候,可以使用二分查找,就不需要一一和前面的元素进行比较了。

解题代码:

class Solution 
{
public:int lengthOfLIS(vector<int>& nums) {//算法>贪心算法vector<int> ret;ret.push_back(nums[0]);int m = nums.size();for(int i = 1; i < m; i++){int num = nums[i];if(num > ret.back()){ret.push_back(num);}else{int left = 0, right = ret.size()-1;while(left < right){int mid = left + (right-left) / 2;if(ret[mid] >= num)right = mid;elseleft = mid+1;}ret[left] = num;}}return ret.size();}
};

 


二、递增的三元子序列

递增的三元子序列

贪心策略:

这道题的贪心策略其实和第一题是一样的。但是我们只需要找长度为3的子序列。并且,我们只需要找到一个结果就可以返回了,不用去找完所有的三元子序列。

解题代码:

class Solution 
{
public:bool increasingTriplet(vector<int>& nums) {int m = nums.size();if(m < 3)return false;vector<int> ret;ret.push_back(nums[0]);for(int i = 1; i < m; i++){if(ret.back() < nums[i])ret.push_back(nums[i]);else{for(int j = 0; j < ret.size(); j++){if(ret[j] >= nums[i]){ret[j] = nums[i];break;}}}if(ret.size() == 3)return true;}if(ret.size() == 3)return true;elsereturn false;}
};

 


三、最长连续递增序列

最长连续递增序列

贪心策略:

用指针 i 固定一个数。然后再来一个指针 j,让这个指针 j 向后移动,去找以 i 位置为起点的最长的连续递增序列。只要 j 位置元素比 j-1 位置元素大,j就往后移动,当 j 位置元素比 j-1 位置元素小就结束,此时就找到了以 i 位置为起点的最长连续的递增序列。

然后,i 移动到 j 位置,以 j 位置为起点,j 向后移动往后找,去找下一个递增子序列。

解题代码:

class Solution 
{
public:int findLengthOfLCIS(vector<int>& nums) {int m = nums.size();int len = INT_MIN;for(int i = 0; i < m;){int j = i+1;while(j < m && nums[j-1] < nums[j])j++;len = max(len, j-i);i = j;}return len;}
};

 


四、买卖股票的最佳时机

买卖股票的最大时机

题目明确要求:股票只能在某一天买入,并在未来某一天卖出。我们先来看看暴力解法。

我们按顺序固定某一天将股票卖出,那么我们就需要在它之前去找到买入股票的时间。

题目要求利润最大,因为我们固定的是卖出,所以收入是知道的,为了利润最大,我们需要在卖出之前找买入股票花费最少的时间。那么,我们就需要从前往后去遍历,使卖出收入减去买入支出的值最大,也就是找股票价格最小的时间。

暴力解法的时间复杂度是 O(n^2)。

贪心策略: 

暴力解法的时间复杂度慢,慢就慢在,我们在找买入股票花费最少的时间时,是从前往后遍历的。

而如果我们使用一个变量来记录在这之前的股票价格的最小值,我们就不再需要从前往后遍历了。

解题代码:

class Solution 
{
public:int maxProfit(vector<int>& prices) {// 算法>贪心算法int maxprofit = INT_MIN;int minprice = prices[0];for(int i = 1; i < prices.size(); i++){maxprofit = max(maxprofit, prices[i] - minprice);minprice = min(minprice, prices[i]);}return maxprofit < 0 ? 0 : maxprofit;}
};

 


五、买卖股票的最佳时机II

买卖股票的最佳时机II

贪心策略:

这道题允许我们多次买卖股票,但是每次只能持有一支股票。

如下图,我们只要找到所有能够获得正收益的一段,就可以将其利润算上。只要是上升的一段区域,我们都可以将其利润拿到。最后的结果就是最大利润。

解题代码:

class Solution 
{
public:int maxProfit(vector<int>& prices) {// 算法>贪心算法int m = prices.size();int maxprofit = 0;for(int i = 0; i < m;){int j = i+1;while(j < m && prices[j-1] < prices[j])j++;if(prices[j-1] > prices[i])maxprofit += prices[j-1]-prices[i];i = j;}return maxprofit;}
};


http://www.ppmy.cn/news/1556117.html

相关文章

【时间序列分析】距离相关系数(Distance Correction)理论及Python代码实现

文章目录 1. 距离相关系数算法介绍2. Python代码实现3. 优缺点及作用4.总结4.1 线性依赖关系4.2 非线性依赖关系4.3 单调依赖关系4.4 复杂依赖关系 1. 距离相关系数算法介绍 距离相关系数&#xff1a;研究两个变量之间的独立性&#xff0c;距离相关系数为0表示两个变量是独立的…

【Linux】基础IO(内存文件)

目录 一、预备知识二、复习常见C语言的文件接口2.1 文件接口的说明2.1.1 fopen函数2.1.2 fputs函数2.1.3 fclose函数 2.2 文件接口的使用 三、认识操作文件的系统调用3.1 系统调用的说明3.1.1 open函数3.1.1.1 Linux中常用的传参方法 3.1.2 write函数3.1.3 close函数 3.2 系统调…

设计模式2

23中设计模式分类 创建型模式&#xff1a;对象实例化的模式&#xff0c;创建型模式用于解耦对象的实例化过程。&#xff08;对象的创建和对象的使用分离&#xff09; 5种&#xff1a;单例模式、工厂模式、抽象工厂模式、原型模式、建造者模式 结构型模式&#xff1a;把类或对…

解决Linux 虚拟机网段与虚拟机配置网段不一致

1.修改静态网络配置 cd /etc/sysconfig/network-scripts/ vim ifcfg-ens33 TYPEEthernet BOOTPROTOstatic NAMEens33 DEVICEens33 ONBOOTyes IPADDR192.168.232.209 NETMASK255.255.255.0 GATEWAY192.168.232.2 DNS18.8.8.8 2.重启网络 systemctl restart network

12月第五讲“ChatGPT在功能测试用例生成方面的优势”

内容简介 本书以目前流行的大语言模型ChatGPT为基础&#xff0c;用丰富的案例演示ChatGPT在软件测试中的赋能作用。本书主要介绍如何用ChatGPT生成需求规格说明书、测试计划、功能测试用例、自动化测试用例、接口测试用例、测试数据和性能测试用例&#xff0c;以及ChatGPT在分析…

【IntelliJ IDEA 集成工具】TalkX - AI编程助手

前言 在数字化时代&#xff0c;技术的迅猛发展给软件开发者带来了更多的挑战和机遇。为了提高技术开发群体在繁多项目中的编码效率和质量&#xff0c;他们需要一个强大而专业的工具来辅助开发过程&#xff0c;而正是为了满足这一需求&#xff0c;TalkX 应运而生。 一、概述 1…

Linux:入门篇——万字长篇解析

Linux:入门篇 目录 Linux:入门篇第一部分&#xff1a;Linux简介与发行版引言前提条件 1. **什么是 Linux&#xff1f;**1.1 Linux 的特点 2. **Linux 的发展历程**3. **Linux 发行版&#xff08;Distributions&#xff09;**3.1 发行版的分类3.2 常见的 Linux 发行版 4. **如何…

HB1910数字IP程控交换机generate.php存在RCE漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…