学习链接:
贪心算法之区间调度问题
扫描线技巧:安排会议室
如何运用贪心思想玩跳跃游戏
1.无重叠区间
题目来源:435. 无重叠区间
题解:
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
int n=intervals.size();
if(n==0) return 0;
sort(intervals.begin(),intervals.end(),[](vector<int>& a,vector<int>& b){
return a[1]<b[1];
});
int end=intervals[0][1];
int cnt=1;
for(auto& i:intervals){
int start=i[0];
if(i[0]>=end)
{
cnt++;
end=i[1];
}
}
return n-cnt;
}
};
2.会议室
// 注意:cpp 代码由 chatGPT🤖 根据我的 java 代码翻译,旨在帮助不同背景的读者理解算法逻辑。
// 本代码还未经过力扣测试,仅供参考,如有疑惑,可以参照我写的 java 代码对比查看。
class Solution {
public:
int minMeetingRooms(vector<vector<int>>& meetings) {
int n = meetings.size();
vector<int> begin(n);
vector<int> end(n);
for(int i = 0; i < n; i++) {
begin[i] = meetings[i][0];
end[i] = meetings[i][1];
}
sort(begin.begin(), begin.end());
sort(end.begin(), end.end());
// 扫描过程中的计数器
int count = 0;
// 双指针技巧
int res = 0, i = 0, j = 0;
while (i < n && j < n) {
if (begin[i] < end[j]) {
// 扫描到一个红点
count++;
i++;
} else {
// 扫描到一个绿点
count--;
j++;
}
// 记录扫描过程中的最大值
res = max(res, count);
}
return res;
}
};
3. 视频拼接
题目来源:1024. 视频拼接
题解:
class Solution {
public:
int videoStitching(vector<vector<int>>& clips, int time) {
if(time==0) return 0;
int n=clips.size();
sort(clips.begin(),clips.end(),[](vector<int>& a,vector<int>& b){
if(a[0]==b[0]) return a[1]>b[1];
else return a[0]<b[0];
});
if(clips[0][0]>0) return -1;
int curend=0;
int nextend=0;
int cnt=0;
int i=0;
while(i<n && clips[i][0]<=curend){
while(i<n && clips[i][0]<=curend){
nextend=max(nextend,clips[i][1]);
i++;
}
cnt++;
curend=nextend;
if(curend>=time)
return cnt;
}
return -1;
}
};
4. 跳跃游戏
题目来源:55. 跳跃游戏
题解:
class Solution {
public:
bool canJump(vector<int>& nums) {
int n=nums.size();
int farther=0;
for(int i=0;i<n-1;i++){
farther=max(farther,i+nums[i]);
if(farther<=i)
return false;
}
return farther>=n-1;
}
};
5. 跳跃游戏II
题目来源:45. 跳跃游戏II
题解:
//题解1:
class Solution {
public:
vector<int> memo;
int jump(vector<int>& nums) {
int n=nums.size();
memo=vector<int>(n,n);
return dp(nums,0);
}
int dp(vector<int>& nums,int p){
int n=nums.size();
if(p>=n-1)
return 0;
if(memo[p]!=n)
return memo[p];
int steps=nums[p];
for(int i=1;i<=steps;i++){
int sub=dp(nums,p+i);
memo[p]=min(memo[p],sub+1);
}
return memo[p];
}
};
//题解2:
class Solution {
public:
int jump(vector<int>& nums) {
int n=nums.size();
int end=0,farthest=0;
int jumps=0;
for(int i=0;i<n-1;i++){
farthest=max(farthest,nums[i]+i);
if(end==i){
jumps++;
end=farthest;
}
}
return jumps;
}
};