专题:贪心算法(已完结)
1.分发饼干
方法一:用最大的胃口 找到最大的饼干(先遍历胃口)
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {// 主要思路 用最大的饼干找最大的胃口sort(g.begin(),g.end());sort(s.begin(),s.end());int j = s.size()-1;int count =0;for(int i=g.size()-1;i>=0;i--){if(j>=0&&g[i]<=s[j]){count++;j--;}}return count;}
};
方法二.用最大的饼干找最大的胃口(先遍历饼干)
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {// 主要思路 用最大的饼干找最大的胃口sort(g.begin(),g.end());sort(s.begin(),s.end());int j =g.size()-1;int count = 0;for(int i =s.size()-1;i>=0;i--){// 遍历饼干while(j>=0&&s[i]<g[j]){//找到合适的胃口j--;}if(j>=0&&s[i]>=g[j]){count++;j--;}}return count;}
};
2.摆动序列
3.最大子序和
思路:之前的和小于0就直接放弃 如果大于0就保持继续累加 比较这能够累加的和的最大值即可
class Solution {
public:int maxSubArray(vector<int>& nums) {// 主要思路是 之前的和小于0就直接放弃 如果大于0就保持继续累加 比较这能够累加的和的最大值即可int sumMax = nums[0];int sum = nums[0];;for(int i=1;i<nums.size();i++){if(sum<0){sum=nums[i];}else{sum=sum+nums[i];}sumMax=max(sumMax,sum);}return sumMax;}
};
4.买卖股票的最佳时机 II
方法一:贪心 主要思路 当天如果与前一天的差值大于0就代表可以这天卖前一天买 累加这种情况即可
方法二:动态规范
方法一:
class Solution {
public:int maxProfit(vector<int>& prices) {// 主要思路 当天如果与前一天的差值大于0就代表可以这天卖前一天买 累加这种情况即可int sum=0;for(int i =1;i<prices.size();i++){if(prices[i]>prices[i-1]){sum=sum+(prices[i]-prices[i-1]);}}return sum;}
};
方法二:
class Solution {
public:int maxProfit(vector<int>& prices) {// 动态规划// 1.定义 dp[i][0] 第i天持有股票的最大利润 dp[i][1] 第i天不持有股票的最大利润// 2.动态转移方程// dp[i][0] = max(dp[i-1][1]-prices[i],dp[i-1][0]);// dp[i][1] = max(dp[i-1][0]+prices[i],dp[i-1][1]);// 3.初始化// dp[0][0] = -prices[0];// dp[0][1]=0;// 4.遍历顺序 从左到右// 返回值 max(dp[prices.size()-1][0],dp[prices.size()-1][1]);vector<vector<int>> dp(prices.size(),vector<int>(2,0));dp[0][0] = -prices[0];dp[0][1]=0;for(int i=1;i<prices.size();i++){dp[i][0] = max(dp[i-1][1]-prices[i],dp[i-1][0]);dp[i][1] = max(dp[i-1][0]+prices[i],dp[i-1][1]);}return max(dp[prices.size()-1][0],dp[prices.size()-1][1]);}
};
5.跳跃游戏
主要思路 就是每次能够跳跃的最远下标位置 如果这个下标位置 刚开始就是无法到达的直接返回false
class Solution {
public:bool canJump(vector<int>& nums) {int maxJumpIndex = 0;for(int i=0;i<nums.size();i++){if(maxJumpIndex<i){return false;}if(i+nums[i]>maxJumpIndex){maxJumpIndex = i+nums[i];}}return true;}
};
6.跳跃游戏 II
主要思路 这里需要记录每次count发生变化的时候 在nextDis 范围内的最大距离是多少。
class Solution {
public:int jump(vector<int>& nums) {if(nums.size()==1){return 0;}int nextDis = 0;int cuDis = 0;int count = 0;for(int i=0;i<nums.size();i++){nextDis = max(i+nums[i],nextDis);if(cuDis==i){count++;cuDis = nextDis;if(cuDis>=nums.size()-1){break;}}}return count;}
};
7.K次取反后最大化的数组和
主要思路:先将绝对值最大的负数去取反 然后如果还剩下剩余取反次数 直接将这些取反次数作用于绝对值最小的正数
class Solution {
public:static bool cmp(int a,int b){return abs(a)>abs(b);};int largestSumAfterKNegations(vector<int>& nums, int k) {// 主要思路是 先将绝对值最大的负数去取反 然后剩余取反次数作用于绝对值最小的正数sort(nums.begin(),nums.end(),cmp);for(int i=0;i< nums.size(); i++){if(nums[i]<0&&k>0){nums[i]=-nums[i];k--;}}if(k%2==1){nums[nums.size()-1]=-nums[nums.size()-1];}int sum=0;for(auto num:nums){sum=sum+num;}return sum;}
};
8.加油站
1.主要思路 首先要明确是否有解 如果总加油量小于总耗油量 无论从哪个站点都不能绕一圈
if(totalGas<totalCost){return -1;}
2.在有解的情况下面 如果当前 的sum<0 则下一个站点可能就是解
sum=sum+(gas[i]-cost[i]);if(sum<0){sum = 0;resultIndex = i+1;}
完整代码如下
class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int totalGas = 0;for(auto g:gas){totalGas=totalGas+g;}int totalCost = 0;for(auto c:cost){totalCost=totalCost+c;}// cout<<"totalGas:"<<totalGas<<" totalCost:"<<totalCost<<endl;if(totalGas<totalCost){return -1;}int resultIndex = 0;int sum = 0;for(int i=0;i<gas.size();i++){sum=sum+(gas[i]-cost[i]);if(sum<0){sum = 0;resultIndex = i+1;}}return resultIndex;}
};
9.分发糖果
主要思路:
1.先从前往后遍历 保证当前高的孩子比前一个孩子糖果多1; preCount
2.再从后往前遍历 保证当前高的孩子比后一个孩子糖果多1; aftercount
3.结合 前preV以及afterV 取最大值即可
class Solution {
public:int candy(vector<int>& ratings) {// 主要思路:// 1.先从前往后遍历 保证当前高的孩子比前一个孩子糖果多1; preCount// 2.再从后往前遍历 保证当前高的孩子比后一个孩子糖果多1; aftercount// 3.结合 前preV以及afterV 取最大值即可//1.前往后遍历vector<int> preCount(ratings.size(),1);for(int i =1;i<ratings.size();i++){if(ratings[i]>ratings[i-1]){preCount[i]=preCount[i-1]+1;}// 默认就是1// else{// preCount[i]=1;// }}//2.从后往前遍历vector<int> aftercount(ratings.size(),1);for(int i =ratings.size()-2;i>=0;i--){if(ratings[i]>ratings[i+1]){aftercount[i]=aftercount[i+1]+1;}// 默认就是1// else{// aftercount[i]=1;// }}//3.结合int count = 0;for(int i=0;i<preCount.size();i++){count=count+max(preCount[i],aftercount[i]);}return count;}
};
10.柠檬水找零
主要思路
客户付款金额 5 美元、10 美元或 20 美元
当客户给5元的时候 不用找 coutFive++;
当客户给10元的时候 找5元 没有5元直接返回false
当客户给20元的时候 优先找一个10元和一个5元 没有的话再找三个5元 还是没有的话 直接false;
```cpp
class Solution {
public:bool lemonadeChange(vector<int>& bills) {//客户付款金额 5 美元、10 美元或 20 美元// 当客户给5元的时候 不用找 coutFive++;// 当客户给10元的时候 找5元 没有5元直接返回false// 当客户给20元的时候 优先找一个10元和一个5元 没有的话再找三个5元 还是没有的话 直接false;int countFive=0,countTem=0,countTwenty=0;for(auto bill: bills){if(bill==5){countFive++;}else if(bill==10){if(countFive==0){return false;}countFive--;countTem++;}else if(bill==20){if(countTem>=1&&countFive>=1){countTem--;countFive--;countTwenty++;}else if(countFive>=3) {countFive=countFive-3;}else{return false;}}}return true;}
};
11.根据身高重建队列
主要思路/:这里有两个维度一个身高h 一个前面大于该元素的个数k 先固定一个元素 例如h 再比较k(插入元素)
先排序
static bool cmp(vector<int> vec1,vector<int> vec2){// 这里有两个维度一个身高h 一个前面大于该元素的个数k 先固定一个元素 例如h 再比较k(插入元素)if(vec1[0]==vec2[0]){return vec1[1]<vec2[1];}return vec1[0]>vec2[0];}
完整代码
class Solution {static bool cmp(vector<int> vec1,vector<int> vec2){// 这里有两个维度一个身高h 一个前面大于该元素的个数k 先固定一个元素 例如h 再比较k(插入元素)if(vec1[0]==vec2[0]){return vec1[1]<vec2[1];}return vec1[0]>vec2[0];}
public:vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {sort(people.begin(),people.end(),cmp);vector<vector<int>> result;for(int i=0;i<people.size();i++){int index = people[i][1];result.insert(result.begin()+index,people[i]);}return result;}
};
12.用最少数量的箭引爆气球
主要思路:先排序 每次比较的是当前元素的左边和上个元素的右边界 发现边界有重复 直接更新当前元素的右边界(在原数据中修改) 没有重复就得增加🗡的个数
if(points[i][0]<=points[i-1][1]){points[i][1] = min(points[i-1][1],points[i][1]);}else{count++;}
完整代码
class Solution {
public:static bool cmp(vector<int> point1,vector<int> point2){return point1[0]<point2[0];} int findMinArrowShots(vector<vector<int>>& points) {// 先排序 每次比较的是当前元素的左边和上个元素的右边界 发现边界有重复 直接更新当前元素的右边界(在原数据中修改) 没有重复就得增加🗡的个数 sort(points.begin(),points.end(),cmp);int count = 1;for(int i=1;i<points.size();i++){if(points[i][0]<=points[i-1][1]){points[i][1] = min(points[i-1][1],points[i][1]);}else{count++;}}return count;}
};
当然 也可以不直接修改原来的数组数据 直接用一个变量记录右边界即可 下面还直接从数据下表index=0开始遍历了 curRightBoundary 要设置长整数型最小值 因为测试用例中有普通整数型最小值
long int curRightBoundary =LONG_MIN;
class Solution {
public:static bool cmp(vector<int> point1,vector<int> point2){return point1[0]<point2[0];} int findMinArrowShots(vector<vector<int>>& points) {// 先排序 发现边界有重复 更新左边界 没有重复就得增加🗡的个数sort(points.begin(),points.end(),cmp);if(points.size()==1){return 1;}long int curRightBoundary =LONG_MIN;int count = 0;for(int i=0;i<points.size();i++){if(points[i][0]<=curRightBoundary){curRightBoundary = min(curRightBoundary,(long int)points[i][1]);}else{count++;curRightBoundary=points[i][1];}}return count;}
};
13.无重叠区间
class Solution {
public:static bool cmp(vector<int> interval,vector<int> interva2){return interval[0]<interva2[0];} int eraseOverlapIntervals(vector<vector<int>>& intervals) {sort(intervals.begin(),intervals.end(),cmp);// for(auto point:intervals){// cout<<point[0]<<" "<<point[1]<<endl;;// }int count =0;for(int i=1;i<intervals.size();i++){if(intervals[i][0]<intervals[i-1][1]){// 有重叠count++;intervals[i][1]=min(intervals[i][1],intervals[i-1][1]);}else{//// 没有重叠 不需要更新边界// count++;}}return count;}
};
14.划分字母区间
主要思路 首先记录s里面每个元素的最远位置 遍历的时候 当如果当前元素到达这个这个元素的最远位置(包含这个元素)的时候 这是一个结果 同时更新左边界
if(rightBoundary==i) {result.push_back(rightBoundary-leftBoundary+1);leftBoundary = i+1;}
完整代码
class Solution {
public:vector<int> partitionLabels(string s) {// 主要思路 首先记录s里面每个元素的最远位置 遍历的时候 当如果当前元素到达这个这个元素的最远位置(包含这个元素)的时候 这是一个结果 同时更新左边界unordered_map<char,int> mymap;for(int i=0;i< s.size();i++){mymap[s[i]]=i;}int leftBoundary =0;int rightBoundary = 0;vector<int> result{};for(int i=0;i< s.size();i++){rightBoundary=max(rightBoundary,mymap[s[i]]);if(rightBoundary==i) {result.push_back(rightBoundary-leftBoundary+1);leftBoundary = i+1;}}return result;}
};
15.合并区间
主要思路:先按照左边界进行排序 从小到大 遍历intervals 如果当前元素和上个元素存在重叠区间 进行合并 否则直接push
class Solution {static bool cmp(vector<int> interval1,vector<int> interval2){return interval1[0]<interval2[0];}
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {// 先按照左边界进行排序 从小到大 遍历intervals 如果当前元素和上个元素存在重叠区间 进行合并 否则直接pushsort(intervals.begin(),intervals.end(),cmp);vector<vector<int>> result{};for(int i=0;i<intervals.size();i++){if(!result.empty()&&intervals[i][0]<=result.back()[1]){result.back()[1]=max(result.back()[1], intervals[i][1]);}else{result.push_back(intervals[i]);}}return result;}
};
16.单调递增的数字
主要思路 从后往前进行遍历 如果当前元素 大于后一个元素 则记录下个元素的位置(这个位置需要变成9) 并且当前元素的值-1(可以直接用to_string进行遍历 以及stoi进行结果输出)
class Solution {
public:int monotoneIncreasingDigits(int n) {// 主要思路 从后往前进行遍历 如果当前元素 大于后一个元素 则记录下个元素的位置(这个位置需要变成9) 并且当前元素的值-1(可以直接用to_string进行遍历 以及stoi进行结果输出)string s = to_string(n);int index=s.size();for(int i=s.size()-2;i>=0;i--){if(s[i]>s[i+1]){index = i+1;s[i]=s[i]-1;}}// cout<<"index:"<<index<<endl;for(int i=index;i<s.size();i++){s[i] = '9';}return stoi(s);}
};
17.监控二叉树
在二叉树章节进行查阅
相关文章:
专题:贪心算法(已完结)
1.分发饼干 方法一:用最大的胃口 找到最大的饼干(先遍历胃口) class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {// 主要思路 用最大的饼干找最大的胃口sort(g.begin(),g.end());so…...
Hadoop的三种运行模式:单机模式、伪分布式模式和完全分布式模式
单机模式 单机模式是Hadoop最简单的运行模式。在单机模式下,所有Hadoop组件都运行在单个机器上,包括HDFS、MapReduce等。由于只有一个节点参与计算,单机模式适用于开发和测试阶段,不适合用于处理大规模数据。在单机模式下…...
JavaScript将array数据下载到Excel中
具体代码如下: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widt…...
【前端】Bootstrap:快速开始
Bootstrap 是一个功能强大且易于使用的前端框架,专门用于创建响应式和移动优先的网页。学习Bootstrap不仅可以帮助你快速构建现代网页,还可以提升你对前端开发流程的理解。本教程将从基础概念开始,逐步引导你掌握Bootstrap,并通过…...
文献阅读(222) VVQ协议死锁
题目:VVQ: Virtualizing Virtual Channel for Cost-Efficient Protocol Deadlock Avoidance时间:2023会议:HPCA研究机构:KAIST request-reply协议死锁如下图所示,每个node收到request之后发送reply,但是想…...
Node.js管理工具NVM
nvm(Node Version Manager)是一个用于管理多个 Node.js 版本的工具。以下是 nvm 的使用方法和一些常见命令: 一、安装 nvm 下载 nvm: 地址:https://github.com/coreybutler/nvm-windows/releases访问 nvm 的 GitHub 仓…...
云原生后端
云原生后端(Cloud-Native Backend)是指在云计算环境中,利用云原生技术(如容器、微服务、服务网格等)构建和部署后端应用程序的一种方法。以下是对云原生后端的详细讲解: 1. 定义 云原生是一种设计和构建应…...
充电宝哪个品牌值得买?2024年五款靠谱充电宝推荐
哪个品牌充电宝值得买?用过这么多款充电宝,个人还是觉得充电快、小巧便携的充电宝使用会更加的方便!在当今快节奏的生活中,手机已成为我们不可或缺的伙伴。然而,随着智能手机功能的日益强大,电池续航问题也…...
YOLOv11对比YOLOV8网络结构变化分析,帮助你真正的理解和学习yolo框架
本文在大佬的文章YOLOv11 | 一文带你深入理解ultralytics最新作品yolov11的创新 | 训练、推理、验证、导出 (附网络结构图)基础上做了一些补充。 一、YOLOv11和YOLOv8对比 二、YOLOv11的网络结构图 下面的图片为YOLOv11的网络结构图。 三、YOLOv11…...
弃用RestTemplate,RestClient真香!
在Spring框架的发展历程中,RestTemplate作为发起HTTP请求的同步API,曾经扮演着举足轻重的角色。然而,随着技术的不断进步和微服务架构的普及,RestTemplate的局限性逐渐显现,尤其是在处理高并发和异步请求时。因此&…...
electron-vite_10electron-updater软件更新
网很多electron-updater更新文章,这里只简单写一下演示代码; 为什么选择 electron-updater插件可以自动更新应用程序,同时支持多个平台;比官方要强; 官方的autoUpdater仅支持macOS 和 Windows 自动更新; 注意是自动,直接更新那种; 脚手架中是…...
React native之全局变量存储AsyncStorage
AsyncStorage是React native中对变量,对象进行全局存储,读取的异步使用对象。以key值进行存储。但是只能存储字符串数据,想存储对象,可把对象JSON进行序列化存储,读取的时候再转成JSON对象。 AsyncStorage.getItem()-…...
获取vue实例
需要注意的是,无论通过哪种方式获取元素,如果元素为 vue 组件,则需要在子组件中使用 defineExpose 进行暴露。 在父组件中,我们静态绑定 childRef: 在子组件中,我们需要通过defineExpose函数,手…...
基于Python实现电影推荐系统
电影推荐系统 标签:Tensorflow、矩阵分解、Surprise、PySpark 1、用Tensorflow实现矩阵分解 1.1、定义one_batch模块 import numpy as np import pandas as pddef read_and_process(filename, sep ::):col_names [user, item, rate, timestamp]df pd.read_cs…...
【linux】进程理解
🔥个人主页:Quitecoder 🔥专栏:linux笔记仓 目录 01.进程的基本概念进程的组成部分进程的特性进程的状态 02.PCBPCB的组成部分task_structtask_struct 的主要组成部分 03.进程属性查看进程 04.通过系统调用创建进程-fork初识工作…...
文件IO练习1
题目一: 1、使用fread和fwrite完成两个文件的拷贝,要求源文件和目标文件由外界输入 实现代码: #define LEN_BUF 256int main(int argc, const char *argv[]) {if(argc ! 3){fprintf(stderr,"程序入参输入有误\n");return -1;}FILE…...
c++ std::future 和 std::promise 的实现工作原理简介
为了便于理解 std::future 和 std::promise 的实现工作原理,我们可以创建一个简化的版本。这包括共享状态、Promise 设置值、Future 获取值的核心机制。我们的示例代码将实现 SimplePromise 和 SimpleFuture 两个类,二者通过一个共享状态实现线程间的通信…...
MATLAB(Octave)混电动力能耗评估
🎯要点 处理电动和混动汽车能耗的后向和前向算法模型(simulink),以及图形函数、后处理函数等实现。构建储能元数据信息:电池标称特性、电池标识符等以及静止、恒定电流和恒定电压等特征阶段。使用电流脉冲或要识别的等效电路模型类型配置阻抗…...
opencv学习:人脸识别器特征提取BPHFaceRecognizer_create算法的使用
BPHFaceRecognizer_create算法 在OpenCV中,cv2.face.LBPHFaceRecognizer_create()函数用于创建一个局部二值模式直方图(Local Binary Patterns Histograms,简称LBPH)人脸识别器。LBPH是一种用于人脸识别的特征提取方法࿰…...
HTML+CSS总结【量大管饱】
文章目录 前言HTML总结语义化标签常用标签H5新的语义元素H5的媒体标签\<embed> 元素(少用)\<object>元素(少用)\<audio>\<video> 元素包含关系iframe元素嵌入flash内容常用表单inputselect CSS总结权重样…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
