前言
这里记录一下陈菜菜的刷题记录,主要应对25秋招、春招
个人背景
211CS本+CUHK计算机相关硕,一年车企软件开发经验
代码能力:有待提高
常用语言:C++
系列文章目录
第35天 :第八章 贪心算法 part04
`
文章目录
- 前言
- 系列文章目录
- 第35天 :第八章 贪心算法 part04
- 一、今日任务
- 二、详细布置
- 452. 用最少数量的箭引爆气球
- 提示:
- 样例1:
- 思路
- 实战
- 踩坑
- 435. 无重叠区间
- 提示:
- 样例1:
- 思路
- 实战
- 踩坑
- 763.划分字母区间
- 提示:
- 样例1:
- 样例2:
- 思路
- 实战
- 总结
一、今日任务
● 452. 用最少数量的箭引爆气球
● 435. 无重叠区间
● 763.划分字母区间
二、详细布置
452. 用最少数量的箭引爆气球
题目链接:力扣452
文章讲解:代码随想录
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。
提示:
1 <= points.length <= 105
points[i].length == 2
-231 <= xstart < xend <= 231 - 1
样例1:
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。
思路
这题感觉很难,但是用贪心算法感觉好简单,很神奇,但是并不好想。
实战
class Solution {
public:
static bool cmp(const vector<int>& a, const vector<int>& b) {
return a[0] < b[0];
}
int findMinArrowShots(vector<vector<int>>& points) {
/*vector<int> res(0);
int i,j,cnt=0;
for(i=0;i<points.size();i++){
for(j=points[i][0];j<=points[i][1];j++)
res[j]++;
}
for(j=0;j<res.size();j++){
if(res[j]>1)
cnt++;
}
return cnt;*/
if(points.size()==0)
return 0;
int cnt=1;
sort(points.begin(),points.end(),cmp);
for(int i=0;i<points.size()-1;i++){
if(points[i+1][0]>points[i][1])
cnt++;
else{
points[i+1][1]=min(points[i + 1][1], points[i][1]);
}
}
return cnt;
}
};
踩坑
两个气球靠在一起并不重叠也可以一起引爆。
435. 无重叠区间
题目链接:力扣435题链接
文章讲解:图文讲解
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
注意 只在一点上接触的区间是 不重叠的。例如 [1, 2] 和 [2, 3] 是不重叠的。
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同
样例1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
思路
这题也是一样,没思路,但是看了题解,好简单!!!
实战
class Solution {
public:
static bool cmp(vector<int>& a,vector<int>& b){
return a[1]<b[1];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if(intervals.size()<=1)
return 0;
int cnt=1;
int end=intervals[0][1];
sort(intervals.begin(),intervals.end(),cmp);
for(int i=1;i<intervals.size();i++){
if(end<=intervals[i][0]){
end=intervals[i][1];
cnt++;
}
}
return intervals.size()-cnt;
}
};
踩坑
一开始的end取得是第一个区间的末端,而不是0,不然会出错。
763.划分字母区间
题目链接:LeetCode763
文章讲解:图文讲解
题目描述
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
提示:
1 <= s.length <= 500
s 仅由小写英文字母组成
样例1:
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。
样例2:
输入:s = "eccbbbbdec"
输出:[10]
思路
本来没有思路,看了题解好简单啊。。。。。
实战
class Solution {
public:
vector<int> partitionLabels(string s) {
vector<int> alphabet(27,0);
vector<int> result;
int i;
int left=0,right=0;
for(i=0;i<s.size();i++){
alphabet[s[i]-'a']=i;
}
for(i=0;i<s.size();i++){
right=max(right,alphabet[s[i]-'a']);
if(i==right){
result.push_back(right-left+1);
left=right+1;
}
}
return result;
}
};
总结
今天主要学习了贪心算法的一系列操作,今天的题目都是看起来很难,一看题解才知道是paper tiger。
加油,坚持打卡的第35天。