当前位置: 首页 > article >正文

代码随想录算法训练营day30

代码随想录算法训练营

—day30

文章目录

  • 代码随想录算法训练营
  • 前言
  • 一、452. 用最少数量的箭引爆气球
  • 二、435. 无重叠区间
  • 三、763.划分字母区间
  • 总结


前言

今天是算法营的第30天,希望自己能够坚持下来!
今日主要是贪心算法的重叠区域问题:
● 452. 用最少数量的箭引爆气球
● 435. 无重叠区间
● 763.划分字母区间


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

题目链接
文章讲解
视频讲解

在这里插入图片描述

思路:
1.先按左区间排序
2.遍历区间,从第二个元素开始判断,当前元素的左区间是否比上一个元素的右区间大
3.是则说明需要多一支箭
4.否则更新当前的右区间,取上一个右区间和当前右区间最小值

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) {
        if (points.size() == 0) 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. 无重叠区间

题目链接
文章讲解
视频讲解

在这里插入图片描述

思路:

  1. 对区间按左边界排序
  2. 判断当前区间的左边界是否比前一个区间的右边界小
  3. 是则证明有有重叠,需要删除,将区间最大的删掉,更新当前区间的右边界(取最小值)

代码如下:

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        return a[0] < b[0]; 
    }

    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.size() == 0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);//左边界排序

        int result = 0;
        for (int i = 1; i < intervals.size(); i++) {
            if (intervals[i][0] >= intervals[i-1][1]) continue; //不重叠
            else {
                result++; //相当于删除了一个区间,因为要删除最小数量,删除右边界最大的区间,留下边界范围小的区间
                intervals[i][1] = min(intervals[i][1], intervals[i-1][1]); //更新当前的右边界
            }
        }

        return result;
    }
};

三、763.划分字母区间

题目链接
文章讲解
视频讲解

在这里插入图片描述

思路:
1.先用一个哈希数组存放每个字母的最远下标
2.遍历字符串,用left记录边界左边,right记录边界右边
3.遍历过程中一直更新right,取当前字母最远下标跟当前right的最大值
3.当遍历到i=right时,说明已经找到一个区间,存下left和right。继续从right+1开始找
(字符串s[i] - ‘a’ 可以让字母从0开始作为hash数组的索引)
代码如下:

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[27] = {0};

        for (int i = 0; i < s.size(); i++) {
            hash[s[i] - 'a'] = i; //更新字母的最远坐标,'a'-'a' = 0
        }

        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 (i == right) {
                result.push_back(right - left + 1); //保存结果
                left = i + 1; //更新左边界,从下一个字母开始
            }
        }
        return result;
    }
};

总结

贪心算法的区间问题:
1.数字的区域,可以先对区域进行按左或右边界排序,然后再遍历区域按照题意判断是否满足要求,然后实时更新当前区域的区间用于下一个循环判断
2.字符的区域,用s[i]-'a’来让字母跟数字下标对应,也是通过不断更新区间来实现

明天继续加油!


http://www.kler.cn/a/506026.html

相关文章:

  • docker安装mysql 5.7
  • C语言初阶习题【30】字符串左旋
  • PHP 使用 Redis
  • 【算法】图解两个链表相交的一系列问题
  • 宇泰串口卡驱动在Ubuntu22.04编译、安装汇总
  • Docker 镜像制作原理 做一个自己的docker镜像
  • python爬虫根据需要查找某个链接并保存
  • 阿里云 EMR 发布托管弹性伸缩功能,支持自动调整集群大小,最高降本60%
  • 如何解决 XGBoost 控制台警告:版本不一致导致的模型加载问题
  • day10_Structured Steaming
  • 【MATLAB代码】CV和CA模型组成的IMM(滤波方式为UKF),可复制粘贴源代码
  • 神经网络常见操作(卷积)输入输出
  • 【微服务】SpringBoot 通用异常处理方案使用详解
  • PyTorch使用教程(3)-Tensor包
  • C语言预处理艺术:编译前的魔法之旅
  • 人工智能-机器学习之多分类分析(项目实战二-鸢尾花的多分类分析)
  • git仓库迁移(从一个平台的仓库迁移到另一个平台的仓库)
  • (处理 Kafka 消息积压) - 高吞吐 + 零丢失的阻塞队列实战方案
  • Android 防止每次打开APP都显示启动页
  • 接口传参 data格式和json格式区别是什么
  • 基于Springboot + vue实现的旅游网站
  • LeetCode 3280. 将日期转换为二进制表示
  • HTML常用元素及其示例
  • react中hooks之useEffect 用法总结
  • 嵌入式Linux:什么是进程?
  • php基本数据结构