贪心算法

贪心算法

452. 最少数量的箭引爆气球

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。


思路:组间按左边界排序,组内选右边界最小,从左往右遍历达到一支箭尽可能射爆更多的气球,达成最少箭射最多气球

435. 无重叠区间

题目描述:给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回需要移除区间的最小数量,使剩余区间互不重叠

注意 只在一点上接触的区间是不重叠的。例如[1, 2][2, 3] 是不重叠的。


思路:先排序,题目要求移除尽可能少的区间,我们就要保留尽可能多的小区间,这样最大程度保证不重叠的同时移除的也少,因此排序策略:按右边界排序,优先放小的,这样重叠的最少,因为右边界确定,不会占用后续区间,而前面已经确定,放小的更容易不重叠,然后将重叠的累加即为答案

763. 划分字母区间

题目描述:给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。例如,字符串 "ababcc" 能够被分为 ["abab", "cc"],但类似 ["aba", "bcc"] 或 ["ab", "ab", "cc"] 的划分是非法的。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。


思路:用自制数组遍历s,得到每个字母最后一次出现的位置,例如s = "ababcbacadefegdehijhklij",a最后一次出现的下标为8,其它同理,再遍历一遍s,边遍历边更新最右位置left = max(left,a[s[i]-'a']),每到一次最右位置left,则result添加该位置+1,再对result数组反向遍历result[i] -= result[i-1],得到每个片段的长度。

56. 合并区间

题目描述:以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。


思路:先将各区间按起点排序,记录终点,然后从前往后遍历,如果起点在终点前则更新终点,不在终点前则添加到结果中,直到遍历完。

重叠区间问题

上述四题都是重叠区间问题,基本只要先排序,将重叠区间尽可能放到一起,然后根据不同题目要求对重叠区间做处理:如 最少数量的箭引爆气球 就是要求重叠得越多越好,表现在代码里就是一只箭占用越多的重叠区间;无重叠区间 则是尽可能放小区间,这样更不容易重叠,要删去区间的也越少; 划分字母区间合并区间 都是不断拓展当前右边界,得到重叠后区间数最少,这类题的贪心我认为主要体现在组间排序组内选择上,组间排序是从大到小还是从小到大,按左边界排序还是右边界排序;组内选择哪个区间或者右边界左边界,厘清这些这些题也应该能收入囊中。

738. 单调递增的数字

题目描述:当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。


思路:优先判断低位是否小于它的高一位,如果小于,数字要最大则低位需要变成9,高位减一,这样满足当前两位数字局部最大,如21,满足单调递增的最大数字为19,同理,从后往前遍历,需注意当某一位从非9变为9,为使整体最大,该位的所有低位也都应该变为9。如2122,后三位满足单调递增,但2122不满足,因此2122的1变为9,后续都应变为9,即1999而非1922。

968.监控二叉树

题目描述:给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。


思路分层放摄像头,确保每层都能被监控,利用flag在层序遍历时标记当前结点状态,如被监控1未被监控0 从叶子结点出发,叶子结点的父结点安摄像头,则整体所用摄像头最少,因此需要采用后序遍历,再根据不同子结点情况决定父节点的状态,我们将状态分为3种:

  1. 无覆盖

  2. 有覆盖

  3. 有摄像头

因为我们需要叶子结点的父结点为有摄像头,因此对于空结点状态为1.有覆盖,这样叶子结点状态就为0.无覆盖,也不需要因为空结点装摄像头。(如果空结点为0.无覆盖则叶子结点就需要装摄像头了)接下来我们分情况讨论父结点与子结点的关系:

1.子结点至少其中一个无覆盖

父结点为2.有摄像头

2.子结点都为有覆盖

父结点为0.无覆盖

3.子结点至少其中一个有摄像头

父结点为1.有覆盖

4.根结点无覆盖

需要在根结点设置摄像头,结果+1

本题贪心策略在于从下往上,摄像头越往上需要的越少,如果是完全二叉树,在叶子结点安摄像头和在叶子结点的父结点安摄像头的数量是随层数指数增长的

posted @ 2025-07-11 09:10  xiaowu52  阅读(6)  评论(0)    收藏  举报