贪心题目总结

1. 最长递增子序列 

我们来看一下我们的贪心策略体现在哪里???

我们来总结一下:

我们在考虑最长递增子序列的长度的时候,其实并不关心这个序列长什么样子,我们只是关心最后一个元素是谁。这样新来一个元素之后, 我们就可以判断是否可以拼接到它的后面。因此,我们可以创建一个数组,统计长度为 x 的递增子序列中,最后一个元素是谁。为了尽可能的让这个序列更长,我们仅需统计长度为x的所有递增序列中最后一个元素的「最小值」。此时我们来算一下时间复杂度,首先我们要遍历整个数组,其次我们还要遍历长度为x的序列,那么此时的复杂度是O(N2),统计的过程中发现,数组中的数呈现「递增」趋势,因此可以使用「二分」来查找插入位置。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> ret;
        ret.push_back(nums[0]);

        for(int i = 1; i < nums.size(); i++)
        {
            if(nums[i] > ret.back())
            {
                ret.push_back(nums[i]);// 如果能接在最后⼀个元素后⾯,直接放
            }
            else
            {
                // 使用二分找到插入位置
                int left = 0;
                int right = ret.size() - 1;
                while(left < right)
                {
                    int mid = (left + right) / 2;
                    if(ret[mid] < nums[i])
                    {
                        left = mid + 1;
                    }
                    else
                    {
                        right = mid;
                    }
                }
                ret[left] = nums[i];// 放在 left 位置上
            }
        }
        return ret.size(); 
    }
};

2. 递增的三元子序列 

我们会发现这道题目就是最递增子序列的简化版,因此我们可以使用贪心的思想,找到最长子序列然后判断长度是否大于3即可解决,但是实际上我们不需要使用二分算法,因为我们只需要求出长度为3的子序列,仅需两次比较就可以找到插入位置,同时不用一个数组存数据,仅需两个变量即可,此时的时间复杂度为O(N).

直接来上代码:

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int a = nums[0];
        int b = INT_MAX;
        for(int i = 0; i < nums.size(); i++)
        {
            if(nums[i] > b) return true;
            else if(nums[i] > a) b = nums[i];
            else a = nums[i];
        }
        return false;
    }
};

3. 最长连续递增序列

这个题目比较简单,找到以某个位置为起点的最长连续递增序列之后(设这个序列的末尾为 j 位置),接下来直接以 j + 1 的位置为起点寻找下⼀个最长连续递增序列,我们没有必要从i + 1位置进行寻找,因为 i 位置找到的序列肯定是最长的!!!

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        int ret = 0;
        int i = 0;
        while(i < nums.size())
        {
            int j = i + 1;
            // 找到递增区间的末端
            while(j < nums.size() && nums[j] > nums[j-1])
            {
                j++;
            }
            ret = max(ret,j - i);
            // 直接在循环中更新下⼀个位置的起点
            i = j; // 贪心
        }
        return ret;
    }
};

4. 买卖股票的最佳时机

首先我们看到这道题目,第一想到的肯定是暴力枚举,我们可以依次枚举两个位置,然后进行相减,最后保存相减出来的最大值即可,但是这样的复杂度就是O(N2)的,此时我们就可以进行优化,我们在枚举卖出价格时候,并不用将前面买入的股票的价格依次枚举,我们只需要找到其中的最小值即可,这一个点就体现出来贪心的策略,由于只能交易⼀次,所以对于某⼀个位置 i ,要想获得最大利润,仅需知道前⾯所有元素的最小值。然后在最小值的位置「买入」股票,在当前位置「卖出」股票即可。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int prevmin = INT_MAX;
        int ret = 0; // 记录最终结果
        for(int i = 0; i < prices.size(); i++)
        {
            // 先更新结果
            ret = max(prices[i] - prevmin, ret);
            // 再更新最小值
            if(prices[i] < prevmin)
                prevmin = prices[i];
        }
        return ret;
    }
};

5. 买卖股票的最佳时机Ⅱ

由于可以进行⽆限次交易,所以只要是⼀个「上升区域」,上升区间一定是稳赚的,我们就把利润拿到手就好了,这就是贪心策略。

⭐解法一:双指针

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int ret = 0;
        for(int i =0 ; i < prices.size(); )
        {
            int j = i;
            while(j + 1 < prices.size() && prices[j + 1] > prices[j])
            {
                j++; // 寻找上升的区间
            }
            ret += prices[j] - prices[i];
            i = j + 1;
        }
        return ret;
    }
};

⭐解法二:拆分交易,只要今天的股票的价格大于昨天,就可以累计到利润上

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        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;
    }
};

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

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

相关文章

C++编程揭秘:虚表机制与ABI兼容性的实例剖析

前言&#xff1a; 假设你的应用程序引用的一个库某天更新了&#xff0c;虽然 API 和调用方式基本没变&#xff0c;但你需要重新编译你的应用程序才能使用这个库&#xff0c;那么一般说这个库是源码兼容&#xff08;Source compatible&#xff09;&#xff1b;反之&#xff0c;如…

CAN总线简介

1. CAN总线概述 1.1 CAN定义与历史背景 CAN&#xff0c;全称为Controller Area Network&#xff0c;是一种基于消息广播的串行通信协议。它最初由德国Bosch公司在1983年为汽车行业开发&#xff0c;目的是实现汽车内部电子控制单元&#xff08;ECUs&#xff09;之间的可靠通信。…

批量漏洞挖掘思路小结

漏洞挖掘是指对应用程序中未知漏洞的探索&#xff0c;通过综合应用各种技术和工具&#xff0c;尽可能地找出其中的潜在漏洞。一般情况下漏洞挖掘针对单一的应用系统&#xff0c;通过端口扫描、目录扫描、文件扫描等方式对其安全性进行评估&#xff0c;而本文主要针对Nday和1day…

软考结束。有什么要说的

1. 竟然是机试&#xff0c;出乎我意料。是 考试机构觉得笔试成本高了么。这次的考试是机试&#xff0c;相比以往有所不一样。感言是不是以后都会在固定地点考试也说不准。 2. 遇到年轻人。 这次旁边的一个女同学第一次参加&#xff0c;还像我询问了一些关于软考的事。我是有…

【设计模式】JAVA Design Patterns——Command(事务模式)

&#x1f50d;目的 将请求封装为对象&#xff0c;从而使你可以将具有不同请求的客户端参数化&#xff0c;队列或记录请求&#xff0c;并且支持可撤销操作。 &#x1f50d;解释 真实世界例子 有一个巫师在地精上施放咒语。咒语在地精上一一执行。第一个咒语使地精缩小&#xff0…

从零实现Llama3中文版

1.前言 一个月前&#xff0c;Meta 发布了开源大模型 llama3 系列&#xff0c;在多个关键基准测试中优于业界 SOTA 模型&#xff0c;并在代码生成任务上全面领先。 此后&#xff0c;开发者们便开始了本地部署和实现&#xff0c;比如 llama3 的中文实现、llama3 的纯 NumPy 实现…

06中间件RTOS/CP

Autosar CP 操作系统详解-CSDN博客 1. 什么是RTOS &#xff1f; RTOS&#xff0c;英文全称是 Real-time Operation System&#xff0c;中文就是 实时操作系统&#xff0c;又称及时操作系统。 实时操作系统&#xff0c;是指当外界事件或数据产生时&#xff0c;能够接受并以足…

【HMGD】STM32/GD32 CAN通信

各种通信协议速度分析 协议最高速度(btis/s)I2C400KCAN1MCAN-FD5M48510MSPI36M CAN协议图和通信帧 CubeMX CAN配置说明 CAN通信波特率 APB1频率 / 分频系数 /&#xff08;BS1 BS2 同步通信段&#xff09;* 1000 ​ 42 / 1 / (111) * 1000 ​ 14,000 KHz ​ 1400000…

【Java面试】二、Redis篇(中)

文章目录 1、Redis持久化1.1 RDB1.2 AOF1.3 RDB与AOF的对比 2、数据过期策略&#xff08;删除策略&#xff09;2.1 惰性删除2.2 定期删除 3、数据淘汰策略4、主从复制4.1 主从全量同步4.2 增量同步 5、哨兵模式5.1 服务状态监控5.2 哨兵选主规则5.3 哨兵模式下&#xff0c;Redi…

Android ListView鼠标模式下ListView回滚问题

概述 在 Android 应用程序中&#xff0c;ListView 是一种常用的控件&#xff0c;用于显示可滚动列表数据。然而&#xff0c;当在鼠标操作模式下使用 ListView 时&#xff0c;可能会遇到一个问题&#xff1a;点击列表项时&#xff0c;列表会回滚到指定位置&#xff0c;这可能会导…

c语言IO

前言 老是忘记c语言IO操作&#xff0c;故写个文章记录一下 打开文件 fopen FILE *fopen(const char *path, const char *mode);mode 返回值 如果文件成功打开&#xff0c;fopen 返回一个指向 FILE 结构的指针。如果文件打开失败&#xff08;例如&#xff0c;因为文件不存…

CMS Full GC流程以及调优配置

个人博客 CMS Full GC流程以及调优配置 | iwts’s blog CMS CMS 收集器是以实现最短 STW 时间为目标的收集器&#xff0c;所以对于偏业务的后台开发而言&#xff0c;基本上都无脑选CMS了。 多线程收集器&#xff0c;工作在老年代&#xff0c;采用标记清除算法。比较特殊&am…

leetcode-顺时针旋转矩阵-111

题目要求 思路 1.假设现在有一个矩阵 123 456 789 2.我们可以根据19这个对角线将数据进行交换&#xff0c;得到矩阵 147 258 369 3.然后将矩阵每一行的数据再翻转&#xff0c;得到矩阵 741 852 963 代码实现 class Solution { public:vector<vector<int> > rot…

贪心-ACW803区间合并-XMUOJ力量碎片合并

题目 思路 附上几个参考链接 for(auto i : v)遍历容器元素_for auto 遍历-CSDN博客 C pair的基本用法总结&#xff08;整理&#xff09;_c pair用法-CSDN博客 使用 sort 实现自定义排序 - AcWing 话不多说&#xff0c;直接上代码 代码 /* ACW803区间合并-XMUOJ力量碎片合…

【C++】二分查找算法:x的平方根

1.题目 2.算法思路 看到题目可能不容易想到二分查找。 这题考察我们对算法的熟练程度。 二分查找的特点&#xff1a;数组具有二段性(不一定有序)。 题目中没有数组&#xff0c;我们可以造一个从0到x的数组&#xff0c;然后利用二分查找找到对应的值即可。 3.代码 class S…

Android 布局中@NULL的使用和代码实现方式详解

文章目录 1、使用场景2、示例代码实现2.1、移除背景2.2 、移除文本2.3、移除布局宽度或高度2.4、移除提示文本2.5、移除图像资源 3、综合示例3.1、布局文件 activity_main.xml3.2、主活动文件 MainActivity.java3.4、资源文件3.5、运行结果 4、优点5、缺点6、综合分析6.1、适用…

MySQL数据库基础:使用、架构、SQL语句、存储引擎

文章目录 什么是数据库CS模式 基本使用安装链接服务器服务器、数据库、表关系简单使用数据库在Linux下的体现 MySQL架构连接器层客户端层服务层存储引擎层物理存储层 SQL分类存储引擎 什么是数据库 mysql&#xff1a;数据库服务的客户端mysqld&#xff1a;数据库服务的服务器端…

BGP策略实验(路径属性和选路规则)

要求&#xff1a; 1、使用preval策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2、使用AS Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3、配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4、使用Local Preference策略&#xff0c;确保R1通过R2到达19…

移动云以深度融合之服务,令“大”智慧贯穿云端

移动云助力大模型&#xff0c;开拓创新领未来。 云计算——AI模型的推动器。 当前人工智能技术发展的现状和趋势&#xff0c;以及中国在人工智能领域的发展策略和成就。确实&#xff0c;以 ChatGPT 为代表的大型语言模型在自然语言处理、文本生成、对话系统等领域取得了显著的…

深度学习中的多GPU训练(Pytorch 20)

一 多GPU训练 下面详细介绍如何从零开始并行地训练网络&#xff0c;这里需要运用小批量随机梯度下降算法。后面我还讲介绍如何使用高级API并行训练网络。 我们从一个简单的计算机视觉问题和一个稍稍过时的网络开始。这个网络有多个卷积层和汇聚层&#xff0c;最后可能 有几个…