【贪心算法】(第十一篇)

目录

坏了的计算器(medium)

题目解析

讲解算法原理

编写代码

合并区间(medium)

题目解析

讲解算法原理

编写代码


坏了的计算器(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

在显⽰着数字 startValue 的坏计算器上,我们可以执⾏以下两种操作:

◦ 双倍(Double):将显⽰屏上的数字乘2;

◦ 递减(Decrement):将显⽰屏上的数字减 1 。

给定两个整数 startValue 和 target 。返回显⽰数字 target 所需的最⼩操作数。

⽰例1:

输⼊:startValue=2,target=3

输出:2

解释:先进⾏双倍运算,然后再进⾏递减运算{2->4->3}.

⽰例2:

输⼊:startValue=5,target=8

输出:2

解释:先递减,再双倍{5->4->8}.

⽰例3:

输⼊:startValue=3,target=10

输出:3

解释:先双倍,然后递减,再双倍{3->6->5->10}.

提⽰:

◦ 1 <= startValue, target <= 10^9

讲解算法原理

解法(贪⼼):
贪⼼策略:
正难则反:

当「反着」来思考的时候,我们发现:

i. 当 end <= begin 的时候,只能执⾏「加法」操作;ii. 当 end > begin 的时候,对于「奇数」来说,只能执⾏「加法」操作;对于「偶数」来

说,最好的⽅式就是执⾏「除法」操作

这样的话,每次的操作都是「固定唯⼀」的。

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
public:
 int brokenCalc(int startValue, int target) 
 {
 // 正难则反 + 贪⼼
 int ret = 0;
 while(target > startValue)
 {
 if(target % 2 == 0) target /= 2;
 else target += 1;
 ret++;
 }
 return ret + startValue - target;
 }
};

java算法代码:

java 复制代码
class Solution
{
 public int brokenCalc(int startValue, int target) 
 {
 // 正难则反 + 贪⼼
 int ret = 0;
 while(target > startValue)
 {
 if(target % 2 == 0) target /= 2;
 else target += 1;
 ret++;
 }
 return ret + startValue - target;
 }
}

合并区间(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

以数组 intervals 表⽰若⼲个区间的集合,其中单个区间为 intervalsi = start(i), end(i) 。请你合并所有重叠的区间,并返回⼀个不重叠的区间数组,该数组需恰好覆盖输⼊中的所有区间。

⽰例1:

输⼊:intervals=\[1,3,2,6,8,10,15,18]

输出:\[1,6,8,10,15,18]

解释:区间1,3和2,6重叠,将它们合并为1,6.

⽰例2:

输⼊:intervals=\[1,4,4,5]

输出:\[1,5]

解释:区间1,4和4,5可被视为重叠区间。

提⽰:

◦ 1 <= intervals.length <= 10^4

◦ intervalsi.length == 2

◦ 0 <= start(i) <= end(i) <= 10^4

讲解算法原理

解法(排序+贪⼼):
贪⼼策略:

a. 先按照区间的「左端点」排序:此时我们会发现,能够合并的区间都是连续的;b. 然后从左往后,按照求「并集」的⽅式,合并区间。

如何求并集:

由于区间已经按照「左端点」排过序了,因此当两个区间「合并」的时候,合并后的区间:a. 左端点就是「前⼀个区间」的左端点;

b. 右端点就是两者「右端点的最⼤值」。

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
public:
 vector<vector<int>> merge(vector<vector<int>>& intervals) 
 {
 // 1. 先按照左端点排序
 sort(intervals.begin(), intervals.end());
 // 2. 合并区间
 int left = intervals[0][0], right = intervals[0][1];
 vector<vector<int>> ret;
 for(int i = 1; i < intervals.size(); i++)
 {
 int a = intervals[i][0], b = intervals[i][1];
 if(a <= right) // 有重叠部分
 {
 // 合并 - 求并集
 right = max(right, b);
 }
 else // 没有重叠部分
 {
 ret.push_back({left, right}); // 加⼊到结果中 left = a;
 right = b;
 }
 }
 // 别忘了最后⼀个区间
 ret.push_back({left, right});
 return ret;
 }
};

java算法代码:

java 复制代码
class Solution
{
 public int[][] merge(int[][] intervals) 
 {
 // 1. 按照左端点排序
 Arrays.sort(intervals, (v1, v2) -> 
 {
 return v1[0] - v2[0];
 });
 // 2. 合并区间 - 求并集
 int left = intervals[0][0], right = intervals[0][1];
 List<int[]> ret = new ArrayList<>();
 for(int i = 1; i < intervals.length; i++)
 {
 int a = intervals[i][0], b = intervals[i][1];
 if(a <= right) // 有重叠部分
 {
 // 合并 - 求并集
 right = Math.max(right, b);
 }
 else // 不能合并
 {
 ret.add(new int[]{left, right});
 left = a;
 right = b;
 }
 }
 // 别忘了最后⼀个区间
 ret.add(new int[]{left, right});
 return ret.toArray(new int[0][]);
 }
}
相关推荐
Logic1019 分钟前
C语言/数据结构二维数组题解:找出行列O个数均为偶数的格子——奇偶性预处理+二次遍历
c语言·数据结构·算法·二维数组·时间复杂度·动态内存分配·奇偶性
程序猿阿森14 分钟前
【机器学习实战】朴素贝叶斯算法详解:从概率基础到商品评论情感分析
算法·机器学习·概率论
余额瞒着我当琳15 分钟前
哈希表底层原理解析,直接定址法,哈希冲突,负载因子,哈希函数,开放定址法
java·c++·哈希算法·散列表
xxwl58526 分钟前
区域赛算法模版第五章---数学与数论
c++·笔记·算法
看浪的路人1 小时前
第6讲:Agent 安全体系——Prompt 注入防御、工具调用审计与输出合规
人工智能·算法
paopaokaka_luck1 小时前
民宿管理系统 (AI民宿总结、协同过滤推荐算法、WebSocket 在线咨询、ECharts 经营分析、房态与结算联动、 民宿预订业务闭环)
java·人工智能·spring boot·websocket·数据分析·echarts·推荐算法
java资料站1 小时前
十四、Spring AI Alibaba · 案例 · 基于 HumanInTheLoop 的内容审核系统
java·spring·状态模式
局部有解1 小时前
LeetCode Hot100 438 找到字符串中所有字母异位词
c++·算法·leetcode
垆边人似月.1 小时前
移动长度 k 子串使字符串变成回文
数据结构·算法
David猪大卫1 小时前
【C++修炼】string类:string类的模拟实现
c语言·开发语言·数据结构·c++·经验分享·笔记·学习