代码随想录:贪心_02

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

class Solution {
public:
    static bool cmp(vector<int> p1,vector<int> p2){
        return p1[0] < p2[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        int cnt = 1;
        sort(points.begin(),points.end(),cmp);
        int x = points[0][1];
        for(int i = 1; i < points.size(); i++){
            if(points[i][0] <= x){
                x = min(points[i][1],x); //更新最小右边界
            }else{
                cnt++;
                x = points[i][1];
            }
        }
        return cnt;
    }
};

435. 无重叠区间

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

class Solution {
public:
    static bool cmp(vector<int> p1,vector<int> p2){
        return p1[0] < p2[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int cnt = 0;
        sort(intervals.begin(),intervals.end(),cmp);
        int x = intervals[0][1];
        for(int i = 1; i < intervals.size(); i++){
            if(intervals[i][0] < x){
                cnt++;
                x = min(intervals[i][1],x); //更新最小右边界
            }else{
                x = intervals[i][1];
            }
        }
        return cnt;
    }
};

763. 划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。

class Solution {
public:
    vector<int> partitionLabels(string s) {
    	//int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置
        //for (int i = 0; i < S.size(); i++) { // 统计每一个字符最后出现的位置
        //    hash[S[i] - 'a'] = i;
        //}
        vector<int> result;
        int left = -1;
        int right = s.rfind(s[0]);
        for(int i = 0; i < s.size(); i++){
            if(i == right){
                result.push_back(right - left);
                left = right;
                right = s.rfind(s[i+1]);
            }
            if(s.rfind(s[i]) > right){
                right = s.rfind(s[i]);
            }
        }
        return result;
    }
};

56. 合并区间

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

class Solution {
public:
    static bool cmp(vector<int> p1,vector<int> p2){
        return p1[0] < p2[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> result;
        sort(intervals.begin(),intervals.end(),cmp);
        int left = intervals[0][0];
        int right = intervals[0][1];
        for(int i = 1; i < intervals.size(); i++){
            if(intervals[i][0] > right){
                result.push_back(vector{left, right});
                left = intervals[i][0];
                right = intervals[i][1];
            }
            right = max(right,intervals[i][1]);
        }
        result.push_back(vector{left, right});
        return result;
    }
};

738. 单调递增的数字

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。
给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string s = to_string(n);
        for(int i = s.size() - 1; i > 0; i--){
            if(s[i - 1] > s[i]){
                s[i - 1]--;
                int j = i;
                while(j < s.size()){
                    s[j] = '9';
                    j++;
                }
            }
        }
        return stoi(s);
    }
};

968. 监控二叉树

给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。

class Solution {
public:
    int result = 0;
    int traversal(TreeNode* node){
        //0无覆盖、1摄像头、2有覆盖
        if(node == NULL) return 2;
        int left = traversal(node->left);
        int right = traversal(node->right);
        if(left == 2 && right == 2)
            return 0;
        if(left == 0 || right == 0){
            result++;
            return 1;
        }
        if(left == 1 || right == 1)
            return 2;
        return -1;
    }
    int minCameraCover(TreeNode* root) {
        if(traversal(root) == 0)
            result++;
        return result;
    }
};

贪心总结

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值