Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Leetcode【435、452、738、991】

Leetcode【435、452、738、991】

作者头像
echobingo
发布于 2019-07-07 16:40:39
发布于 2019-07-07 16:40:39
73800
代码可运行
举报
运行总次数:0
代码可运行
问题描述:【Greedy】435. Non-overlapping Intervals
解题思路:

这道题是给一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

实际上,这道题和 贪心算法之活动安排问题 很类似,贪心策略应该是每次选取结束时间最早的活动。直观上也很好理解,按这种方法选择相容活动为没有安排的活动留下尽可能多的时间。这也是把各项活动按照结束时间单调递增排序的原因。

到这道题中,我们求的是“不相容的活动”的数量。还是同样的做法,先按照右区间从小到大排序,然后遍历数组,找到重叠的区域(不相容的活动),将结果加 1;如果相容,指针向后移动。

Python3 实现:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        N = len(intervals)
        ans = 0
        intervals.sort(key=lambda x: x[1])  # 按照结束时间升序
        i, j = 0, 1
        while i < N and j < N:
            if intervals[j][0] < intervals[i][1]:  # 有重叠,要删除一个
                ans += 1
            else:  # 不重叠
                i = j
            j += 1
        return ans

print(Solution().eraseOverlapIntervals([[1,100],[11,22],[1,11],[2,12]]))  # 2

问题描述:【Greedy】452. Minimum Number of Arrows to Burst Balloons
解题思路:

这道题实际上是给一个气球区间的集合,求用最少数量的箭引爆所有气球。

我们的目的是用最少的箭来引爆所有气球,因此我们要尽量保证一支箭能穿过足够多的气球区间。其实,这道题和上面的 Leetcode 435 很类似,也属于活动时间安排问题。

因此,我们先按照右区间进行升序排列,遍历区间的过程中,左区间如果小于前面区间的右区间,说明两者有重叠;否则,说明需要增加一支箭来满足后面的区间。这种贪婪的思想可以保证尽量多的区间合并,因此能得到最少的箭数。

Python3 实现:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        N = len(points)
        if N == 0:
            return 0
        points.sort(key=lambda x: x[1])
        ans = 1
        i, j = 0, 1
        while i < N and j < N:
            if points[j][0] > points[i][1]:  # 两者没有重叠,增加一支箭
                i = j
                ans += 1
            j += 1
        return ans

问题描述:【Math】738. Monotone Increasing Digits
解题思路:

这道题是给一个数字 N,找到小于等于 N 的单调递增数字。

这道题需要找规律,我们先全排列一下 148 看一下结果:

148 -> 148;184 -> 179;418 -> 399;481 -> 479;814 -> 799;841 -> 799

由上面可以发现规律:从左到右遍历每一位数字,找到第一个逆序对(如 481 的第一个逆序对是 (8, 1));然后,将逆序对的第一个位置处的数字减 1,后面补够 9;最后,答案为:逆序对前面的数字 + 逆序对位置处数字减 1 + 逆序对后面补够 9。

以 481 为例,做法如下:

  • 使用两个指针 i 和 j,i 指向 4,j 指向 8;
  • 因为 4 < 8,则 i 和 j 都向后移动,i 指向 8,j 指向 1;
  • 因为 8 > 1,则找到第一个逆序对,8-1=7,后面补 9,最后得到答案 479。

注意:如果是 13555884 这种,结果应该为 13555799,但是按照上述规律会得到 13555879 的错误答案。因此,如果前面不是严格递增,i 不滑动(停留在第一个 8 的位置),只有 j 滑动(滑动到 4),这样我们就能定位第一个 8 的位置,从而得到正确答案。

Python3 实现:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution:
    def monotoneIncreasingDigits(self, N: int) -> int:
        S = str(N)
        i, j = 0, 1
        while i < len(S) and j < len(S):
            if S[i] < S[j]:  # 如果严格递增,i和j都向后滑动
                i = j; j += 1
            elif S[i] == S[j]:  # 如果非严格递增,只有j向后滑动 
                j += 1
            else:  # S[i]>S[j],即第一个逆序对位置
                return int(S[:i] + str(int(S[i]) - 1) + '9' * (len(S) - i - 1))
        return N

问题描述:【Math】991. Broken Calculator
解题思路:

这道题是给 X 和 Y,X 每次只能执行乘 2 或者减 1 操作,求得到 Y 所需的最少操作步数。

很明显,如果 X >= Y,那么 X - Y 就是最后的答案。对于 X < Y,刚开始想的是用广搜 BFS 求解: 从M走到N最少步数,但是由于 X 和 Y 的取值范围都为 10^9 次方,开辟一个 10^9 的空间会造成内存溢出(最大只能开 10^8 次方的空间大小)。

那么,这道题很明显不是这样求解的,具体怎么做呢?我们可以从下面的例子中观察到一些规律:

X = 3,Y = 8:3 -> 2 -> 4 -> 8;

X = 5,Y = 8:5 -> 4 -> 8;

X = 6,Y = 8:6 -> 5 -> 4 -> 8;

X = 7,Y = 8:7 -> 6 -> 5 -> 4 -> 8;

X = 7,Y = 9:7 -> 6 -> 5 -> 10 -> 9;

我们发现,可以使用逆向思维,即从 Y 到 X 去考虑。当 Y > X 时,如果 Y 为奇数,就执行加 1 操作;如果 Y 为偶数,就执行除以 2 操作。当 Y 变得比 X 小后(如 X = 7,Y = 9 中,Y 变成了 5 后,5 < X),再一步一步执行加 1 的操作,最终得到 X。

这是一种贪婪的思想,即每次考虑让 Y 先除以 2,不行的话再执行加 1 操作。时间复杂度为 O(log Y),空间复杂度为 O(1)。

为什么这样会得到正确的答案?以下是证明,写得很清楚:坏了的计算器题解

Python3 实现:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution:
    def brokenCalc(self, X: int, Y: int) -> int:
        ans = 0
        while Y > X:  # 从YX逆向思维考虑
            if Y % 2 == 1:  #Y为奇数+1
                Y += 1
            else:  #Y为偶数除以2
                Y //= 2
            ans += 1
        return ans + (X - Y)  # 最后还要加上X-Y,即Y<=X后,X一步一步到达Y
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.07.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​LeetCode刷题实战452:用最少数量的箭引爆气球
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2021/12/06
3830
穿上衣服我就不认识你了?来聊聊最长上升子序列
最长上升子序列是一个很经典的算法题。有的会直接让你求最长上升子序列,有的则会换个说法,但最终考察的还是最长上升子序列。那么问题来了,它穿上衣服你还看得出来是么?
lucifer210
2020/06/29
7890
穿上衣服我就不认识你了?来聊聊最长上升子序列
为了得到无重叠区间,煞费苦心
力扣题目链接:https://leetcode-cn.com/problems/non-overlapping-intervals
代码随想录
2021/12/09
3630
为了得到无重叠区间,煞费苦心
​LeetCode刷题实战435:无重叠区间
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2021/11/15
3700
Leetcode【56、670】
首先可以想到按照区间的起始点进行升序排序。假设合并后的区间保存在数组 ans 中。从左到右遍历各个区间 interval,会有以下 3 种情况:
echobingo
2019/10/12
5440
力扣每日一刷(2023.9.7)
根据题目中给出的条件开始坐标总是小于结束坐标。 ,首先可以按照开始坐标进行排序,以案例一为例:
用户11097514
2024/05/31
920
LeetCode-贪心算法
题目描述:每个孩子都有一个满足度,每个饼干都有一个大小,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。
LittlePanger
2020/04/14
3900
运用贪心算法来做时间管理
东哥带你手把手撕力扣~ 作者:labuladong 公众号:labuladong 若已授权白名单也必须保留以上来源信息
labuladong
2021/09/23
5990
Leetcode【392、870、881、1090】
简单题。双指针 i 和 j 分别指向 t 和 s,对于 t 的每一个位置遍历,如果 t[i] 和 s[j] 相同,那么 j 也想后移动找下一个相同的字符。当 j 达到 s 的长度,返回 True,否则 s 不是 t 的子序列,返回 False。
echobingo
2019/07/08
5260
搞定大厂算法面试之leetcode精讲4.贪心
贪心法,又称贪心算法,贪婪算法,在对问题求解时,总是做出在当前看来最好的选择,期望通过每个阶段的局部最优选择达到全局最优,但结果不一定最优
全栈潇晨
2021/11/23
6290
搞定大厂算法面试之leetcode精讲4.贪心
【区间贪心】合并区间 / 无重叠区间 / 用最少数量的箭引爆气球 / 俄罗斯套娃信封问题
贪心策略:我们在射箭的时候,要发挥每一支箭最大的作用,应该把互相重叠的区间统一引爆。
_小羊_
2025/04/09
720
【区间贪心】合并区间 / 无重叠区间 / 用最少数量的箭引爆气球 / 俄罗斯套娃信封问题
Leetcode大大,对不起你,我把你当成测试平台了
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
小码匠
2022/06/16
2750
Leetcode大大,对不起你,我把你当成测试平台了
JavaScript刷LeetCode拿offer-贪心算法
学习算法的时候,总会有一些让人生畏的名词,比方动态规划,贪心算法 等,听着就很难;而这一 part 就是为了攻破之前一直没有系统学习的 贪心算法;
hellocoder2028
2022/11/02
4160
用javascript分类刷leetcode4.贪心(图文视频讲解)
贪心法,又称贪心算法,贪婪算法,在对问题求解时,总是做出在当前看来最好的选择,期望通过每个阶段的局部最优选择达到全局最优,但结果不一定最优
hellocoder2028
2022/12/15
3670
LeetCode 435. 无重叠区间(贪心/动态规划)
注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
Michael阿明
2020/07/13
1.1K0
【代码随想录】二刷-贪心算法
贪心算法 什么是贪心? 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 贪心没有规定的套路。 刷题或面试的时候,手动模拟一下感觉可以局部最优退出整体最优,而且想不到反例,那么就试一试贪心。 贪心算法一般分为如下四步: 将问题分为若干子问题 找出合适的贪心策略 求解每一个子问题的最优解 将局部最优解堆叠成全局最优解 ---- 455. 分发饼干 方法1: 充分利用每个饼干的大小,用大块的饼干优先喂饱大胃口的孩子 class Solution { public:
半生瓜的blog
2023/05/13
4640
【代码随想录】二刷-贪心算法
数字问题-LeetCode 452、453、454、455、456、459(KMP算法)
在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以y坐标并不重要,因此只要知道开始和结束的x坐标就足够了。开始坐标总是小于结束坐标。平面内最多存在104个气球。
算法工程师之路
2020/02/13
8080
贪心算法总结(4)
小陈在拼命
2024/08/21
1190
贪心算法总结(4)
贪心算法之区间调度问题
什么是贪心算法呢?贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高。
帅地
2019/08/26
1.1K0
贪心算法之区间调度问题
Leetcode 【583、809、816】
这道题目是给两个单词 word1 和 word2,每次只能从中删除一个字符,最后两单词相等,求最少删除次数。
echobingo
2019/07/03
6290
推荐阅读
相关推荐
​LeetCode刷题实战452:用最少数量的箭引爆气球
更多 >
LV.0
这个人很懒,什么都没有留下~
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验