贪心算法

  • 前言
  • 455.分发饼干
  • 135.分发糖果
  • 435.无重叠区间
  • 605.种花问题
  • 452.用最小数量的箭引爆气球
  • 763.划分字母区间
  • 122. 买卖股票的最佳时机 II
  • 376. 摆动序列
  • 53. 最大子序和

前言

贪心算法或贪心思想采用贪心的策略,保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的。

455.分发饼干


题解
因为饥饿度最小的孩子最容易吃饱,所以我们先考虑这个孩子。为了尽量使得剩下的饼干可以满足饥饿度更大的孩子,所以我们应该把大于等于这个孩子饥饿度的、且大小最小的饼干给这个孩子。满足了这个孩子之后,我们同样的策略,考虑剩下孩子里饥饿度最小的孩子,直到没有满足条件的饼干存在。

简而言之,这里的贪心策略是,给剩余孩子里最小饥饿度的孩子分配最小的能饱腹的饼干。

至于具体实现,因为我们需要获得大小关系,一个便捷的方法就是把孩子和饼干分别排序。

这样我们就可以从饥饿度最小的孩子和大小最小的饼干出发,计算有多少个对子可以满足条件。


注意: 对数组或字符串排序是常见的操作,方便之后的大小比较。

注意: 在之后的讲解中,若我们谈论的是对连续空间的变量进行操作,我们并不会明确区分数组和字符串,因为他们本质上都是在连续空间上的有序变量集合。一个字符串“abc”可以被看作一个数组 [‘a’,‘b’,‘c’]。

C++代码

class Solution {public:int findContentChildren(vector<int>& children, vector<int>& cookies) {sort(children.begin(), children.end());sort(cookies.begin(), cookies.end());int child = 0, cookie = 0;//初始化两个指针,一个指向第一个小孩,另一个指向第一个饼干。while (child < children.size() && cookie < cookies.size()) //指针在正常范围内,运行{if (children[child] <= cookies[cookie]) ++child;//如果第cookie个cookies 比第child个childern大,说明第child个childern可以被满足,于是小孩与饼干指针同时向后移动。++cookie;//如果饼干不能满足小孩,那么饼干指针向下移}//直到某个指针超范围,返回满足的小孩数return child;}
};

135.分发糖果


解题
虽然这道题leetcode规定为困难,但我觉得这道题是贪心算法中简单的一种。
首先,我们需要初始化一个全为1的数组,从右向左遍历数组,如果左边比右边大,那么左边就在右边基础上加一;再从左向右遍历数组,如果右边比左边大,右边就在左边的基础上加一;
这里的贪心策略就是只考虑相邻两位的关系

代码

class Solution {public:int candy(vector<int>& ratings) {int size = ratings.size();if(size<2){return size;}//如果只有一个,那么就直接返回1就可以vector<int> nums(size,1);//初始化全为一的数组for(int i = 1;i<size;++i)//从左向右扫描,如果右边比左边大,那么右边在左边的基础上加一{if(ratings[i]>ratings[i-1]){nums[i]=nums[i-1]+1;}}for(int i = size-1;i>0;--i)//从右边向左边扫描,如果右边比左边大,再比较一下是本身大,还是右边加一大。{if(ratings[i-1]>ratings[i]){nums[i-1]= max(nums[i-1],nums[i]+1);}}return accumulate(nums.begin(), nums.end(), 0);//返回数组中所有元素的和}
};

435.无重叠区间

解题
在选择要保留区间时,我们应该注意区间的结尾,我们选择的区间结尾越小,那么我们保留下来的区间就越多,因此我们采取的贪心策略为,优先保留结尾小且不相交的区间。

那么如何实现呢?
首先,先把区间按照结尾的大小排序;然后,每次选取结尾最小的且和前一个选择的区间不重叠的区间。这就需要用到C++ 的lambda,并结合std::sort()函数进行自定义排序

代码

class Solution {public:int eraseOverlapIntervals(vector<vector<int>>& intervals) {if(intervals.empty()){return 0;}int n = intervals.size();sort(intervals.begin(),intervals.end(),[](vector<int> a,vector<int> b){return a[1] < b[1];});//C++ lambda函数自定义排序,如果看不懂,请移步C++基础int abandon  = 0,prev = intervals[0][1];//初始化prev指针指向第一组第二个数for(int i = 1;i<n;++i){if(intervals[i][0]<prev)//如果后一组第一个数小于前一组第二个数,说明区间有重复,需要舍弃后一组(原因建见题解),所以abandon加一。{++abandon;}else{prev = intervals[i][1];}//如果后一组第一个数大于这一组第二个数,那么prev指向这一组。}return abandon;}
};

605.种花问题

题解
这道题的贪心策略就是能种就种

代码

class Solution {public:bool canPlaceFlowers(vector<int>& flowerbed, int n) {int ans =0;for(int i = 0 ;i <flowerbed.size();++i)//遍历{if(flowerbed[i]==0 && (i+1 == flowerbed.size() || flowerbed[i+1] == 0)&& (i == 0 || flowerbed[i-1] == 0))//判读是否能种,能种就种。首先当前位置是0;其次,当前位置是末尾或者下一个位置是0;然后,当前位置是首位,或者前一个位置是0。这样的位置你就可以欢乐的种花花了。{flowerbed[i]= 1;ans += 1;//种花位置加1}}return ans >= n;}
};

452.用最小数量的箭引爆气球


题解
这道题看着挺长,其实很简单

注意这是按末尾坐标排序的
排序后如何放箭就显而易见了,第一把箭放在黄色框末尾,第二把箭放在蓝色框框末尾

代码

class Solution {public:int findMinArrowShots(vector<vector<int>>& points) {if (points.empty()) {return 0;}sort(points.begin(), points.end(), [](const vector<int>& u, const vector<int>& v) {return u[1] < v[1];});//通过C++ lambda函数对每组坐标以末尾进行排序int pos = points[0][1];//初始化第一把箭的位置为第一个气球右坐标。int ans = 1;//如果有气球,一定会使用一支箭。for (const vector<int>& balloon: points) {if (balloon[0] > pos)//如果某个气球的左坐标大于箭的位置,说明它已经超出了第一支箭所能射击的范围,所以箭数加一 ,并将这个气球的右坐标设置为喜下一支箭的初始位置。{pos = balloon[1];++ans;}}return ans;//返回箭数}
};

763.划分字母区间


题解
遍历字符串,通过哈希表或者数组记录每个字母最后一次出现的位置;再遍历字符串,设遍历第iii个字母,且当前字母最后出现的位置为endiendiendi,end=max(end,endi)end = max(end,endi)end=max(end,endi),当i=endi=endi=end时说明前i+1i+1i+1为一个符合题意的片段;初始化startstartstart为end+1end+1end+1,重复上述操作
如果理解不了,可以画画,就明白了。

代码

class Solution {public:vector<int> partitionLabels(string S) {int last[26];//此数组将用于保存每个字母最后出现的位置int length =S.size();for(int i =0;i<length;++i){last[S[i]-'a'] = i;//记录每个字母最后出现的位置}vector<int> partition;int start = 0,end =0;for(int i =0;i<length;++i){end = max(end,last[S[i]-'a']);//寻找边界if(i == end ){partition.push_back(end-start+1);start = end +1;}}return partition;}
};

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


题解
贪心策略:涨了就卖。至于为什么第二天涨了就卖出呢,因为在持续增长的情况下接连卖出和涨到最高点卖出获利是一样的,所以只要第二天涨了就卖出。

代码

//太简单了,实在是没什么好注释的!!!!
class Solution {public:int maxProfit(vector<int>& prices) {int res =0;for(int i =1; i < prices.size();++i){if(prices[i]>prices[i-1]){res += prices[i] -prices[i-1];}}return res;}
};

376. 摆动序列

题解

代码

class Solution {public:int wiggleMaxLength(vector<int>& nums) {if(nums.size()<2) return nums.size();int cur =0;int pre =0;int result =1;for(int i =1;i<nums.size();++i){cur = nums[i]-nums[i-1];if((pre >= 0 && cur <0) || (pre<=0 && cur>0)){++result;pre =cur;}}return result;}
};

53. 最大子序和

代码
先来个暴力算法

class Solution {public:int maxSubArray(vector<int>& nums) {int result = INT32_MIN;int count = 0;for (int i = 0; i < nums.size(); i++) { // 设置起始位置count = 0;for (int j = i; j < nums.size(); j++) { // 每次从起始位置i开始遍历寻找最大值count += nums[j];result = count > result ? count : result;}}return result;}
};

贪心算法


持续更新中

贪心算法(leetcode分类解题,C++代码详细注释)相关推荐

  1. 【综合评价分析】熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列

    [综合评价分析]熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列 文章目录 1. 熵权法确定指标权重 (1)构造评价矩阵 Ymn (2)评价矩阵标准化处理 (3)计算指标信息熵值 Mj ...

  2. 手写YOLOv3|代码详细注释

    手写YOLOv3|代码详细注释 一. 数据预处理 一. Yolov3网络 一. Train 一. Detection 源代码:https://github.com/eriklindernoren/Py ...

  3. c语言期中项目实战二—简易扫雷,思路分析加代码详细注释

    c语言期中项目实战二-简易扫雷,思路分析+代码详细注释 游戏介绍 项目步骤 模块化编程 设置菜单 设置棋盘 打印棋盘 布置雷 排查雷 总结及总代码和详细注释 游戏介绍 扫雷这个经典游戏,直到现在仍有很 ...

  4. 【Python】python初学者应该知道与其他语言差异化的高效编程技巧(附测试代码+详细注释)

    目录 1. 交换变量 2. 集合去重 3. 列表推导.集合推导和字典推导 4. 统计字符串中各个字符出现的次数 5.优雅地打印JSON数据 6.行内的if语句 6. 符合正常逻辑的数值比较 7. 田忌 ...

  5. 【综合评价分析】topsis评价 原理+完整MATLAB代码+详细注释+操作实列

    [综合评价分析]topsis评价 原理+完整MATLAB代码+详细注释+操作实列 文章目录 1.TOPSIS法的原理 2.TOPSIS法案例分析 3.建立模型并求解 3.1数据预处理 3.2代码实现数 ...

  6. 双指针法(leetcode分类解题,C++代码详细注释)

    双指针法 前言 167.两数之和 II - 输入有序数组 88.合并两个有序数组 142. 环形链表 II 633.平方数之和 680. 验证回文字符串 Ⅱ 27. 移除元素 344. 反转字符串 剑 ...

  7. 贪心算法思想详解+示例代码

    CSDN话题挑战赛第2期 参赛话题:学习笔记 文章目录 五大算法思想 贪心算法 举例说明 选择排序 删除数字 寻找数字最大和 买股票 最大回文字符串 背包问题 小结 五大算法思想 分治思想 贪心算法/ ...

  8. 吴恩达机器学习 逻辑回归 作业3(手写数字分类) Python实现 代码详细解释

    整个项目的github:https://github.com/RobinLuoNanjing/MachineLearning_Ng_Python 里面可以下载进行代码实现的数据集 题目介绍: In t ...

  9. 吴恩达机器学习 神经网络 作业1(用已经求好的权重进行手写数字分类) Python实现 代码详细解释

    整个项目的github:https://github.com/RobinLuoNanjing/MachineLearning_Ng_Python 里面可以下载进行代码实现的数据集 题目介绍: In t ...

最新文章

  1. 10JavaScript中的预解析
  2. 如何写出让 CPU 跑得更快的代码?
  3. 关键字—修饰方法、类、属性和变量的关键字(共9个)
  4. sqlserver数据库中char、varchar、text与nchar、nvarchar、ntext数据类型使用详解
  5. python与专业相结合应用案例_Office高级应用与Python综合案例教程(普通高等教育十三五规划教材)...
  6. shell脚本基础 循环机构
  7. php项目升级包制作,PHP项目安全:PHP的安装与升级
  8. P-Associated-URI处理流程
  9. Drool规则引擎入门实例
  10. 软件测试项目案例.pdf,【精选】最经典软件测试案例.pdf
  11. 小学-知识与能力【5】
  12. 从此就学会了...笑着哭......
  13. linux如何启动网络配置文件,linux系统的网络配置教程 Ubuntu系统网络设置方法网络配置linux及Ubuntu通过修改配置文件进行网络配置...
  14. Mac免费思维导图软件:幕布 for mac
  15. 大数据技术之高频面试题
  16. CMW500 Bluetooth信令测试
  17. kubernetes的部署架构以及工作原理
  18. 详解程序员驻场开发服务的具体流程
  19. 穷爸爸与富爸爸读后感(3)
  20. Bentley版隧道

热门文章

  1. 取模运算性质_求余、取模运算在RTOS中计算优先级的理解
  2. postgresql返回行数_怎么优化你的SQL查询?以PostgreSQL为例
  3. 机器学习的练功心法(三)——特征工程
  4. [react] 在React中组件的state和setState有什么区别?
  5. 带你封装一个上传图片组件(ant design+react)
  6. 深入react技术栈(12):组件内通信
  7. Taro+react开发(30)引入静态资源地址
  8. 工作373-前端 import与export区别
  9. [css] css中padding和margin是相对于父元素还是子元素呢?
  10. 工作308:控制change