代码随想录打卡第三十天

代码随想录–贪心算法

day 30 贪心算法第四天
居然过了一半了



一、力扣452–用最少数量的箭引爆气球

代码随想录题目链接:代码随想录

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

简单来说就是需要一箭双雕或者三雕

难点在于怎么写,思路并不是最难的

用vector储存的气球可以排序,按照起点从小到大排序

依次检查第i个气球和i-1是否挨着,如果断开了,那么说明这之前必须有一个箭

如果挨着,那么就可以把这两个气球合并成一个气球了,具体做法是更新i的结尾,用i和i-1结尾更小者代替

代码如下:

class Solution {
public:
    static bool cmp(vector<int>& a, vector<int>& b)
    {
        return a[0] < b[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        if(!points.size()) return 0;
        sort(points.begin(), points.end(), cmp);
        int result = 1;
        for(int i = 1; i < points.size(); i ++)
        {
            if(points[i][0] > points[i-1][1])
            {
                result++;
            }
            else points[i][1] = min(points[i][1], points[i-1][1]);
        }
        return result;
    }
};

二、力扣435–无重叠区间

代码随想录题目链接:代码随想录

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

思路是记录不重叠的区间个数,那么用几何长度减去这个数字,就是要移除的数量

代码如下:

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()) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int result = 1;
        int end = intervals[0][1];
        for(int i = 1; i < intervals.size(); i ++)
        {
            if(end <= intervals[i][0])
            {
                end = intervals[i][1];
                result ++;
            }
        }
        return intervals.size() - result;
    }
};

三、力扣763–划分字母区间

代码随想录题目链接:代码随想录

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
返回一个表示每个字符串片段的长度的列表。

在这里插入图片描述

看图写作,基本上就能完成了

用hash表记录下来每个字母最后出现的位置

然后用right和left进行切割,遍历字符串,right等于每个元素最后出现的位置

当right代表的数字与下标重合,那么说明此时可以切割了,切出来left到right这一段,再把left更新一下即可

代码如下:

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[26] = {0};
        for(int i = 0; i < s.size(); i ++) hash[s[i] - 'a'] = i;
        vector<int> result;
        int left = 0;
        int right = 0;
        for(int i = 0; i < s.size(); i ++)
        {
            right = max(right, hash[s[i] - 'a']);
            if(right == i)
            {
                result.push_back(right - left + 1);
                left = i + 1;
            }
        }
        return result;
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值