代码随想录刷题笔记 DAY 35 | 无重叠区间 No.435 | 划分字母区间 No.763 | 合并区间 No.56

文章目录

    • Day 35
      • 01. 无重叠区间(No. 435)
        • <1> 题目
        • <2> 笔记
        • <3> 代码
      • 02. 划分字母区间(No. 763)
        • <1> 题目
        • <2> 笔记
        • <3> 代码
      • 03. 合并区间(No. 56)
        • <1> 题目
        • <2> 笔记
        • <3> 代码

Day 35

01. 无重叠区间(No. 435)

题目链接

代码随想录题解

<1> 题目

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

示例 1:

输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

提示:

  • 1 <= intervals.length <= 105
  • intervals[i].length == 2
  • -5 * 104 <= starti < endi <= 5 * 104
<2> 笔记

本题和昨天的用最少的箭引爆气球比较类似

代码随想录刷题笔记 DAY 34 | 柠檬水找零 No.860 | 根据身高重建队伍 No.406 | 用最少的箭引爆气球 No.452

首先,如果要找到删除哪些段能够使得这个数组没有重叠的部分,首先需要 想办法将最有可能重叠的段聚集起来,所以先按照 起点的大小 进行递增排序,这样排序过后可能重叠的段就在一起了。

现在来思考如何判断两个段是否重合呢?

答案是当发现上一段的 right 是大于下一段的 left 的时候说明两端是重合的,因为经过排序以后上一段的 起点一定小于等于下一段的起点

这时候为了使得没有重叠是 一定要删除其中的一段的,那删除那一段好呢?

答案是删除 right 最大的段,因为这种段的 覆盖面积 最大;所以可以得到这样的策略:遍历数组时当发现有重叠后就删除两段之中 right 最大的段。

所以在上一张图中,删除的就是第二个段,找不出反例,试试贪心。

首先对数组进行排序

Arrays.sort(intervals, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        return Integer.compare(o1[0], o2[0]);
    }
});

然后去循环遍历整个数组,当遇到重叠的部分就删除 最大 的那个

        int maxRight = intervals[0][1];
        int res = 0;
        for (int i = 0; i < intervals.length; i++) {
            // 说明这两个节点是重叠的
            if (intervals[i][0] < maxRight) {
                res++;
                maxRight = Math.min(intervals[i][1], maxRight); // 删除掉最宽的哪一个
            } else {
                // 此时不是重叠的,切换 right
                maxRight = intervals[i][1];
            }
        }

但是此时的数组是从 0 开始遍历的,所以在第一次遍历的时候会多加上一个 1,返回结果的时候应该返回 res - 1

<3> 代码
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return Integer.compare(o1[0], o2[0]);
            }
        });
        int maxRight = intervals[0][1];
        int res = 0;
        for (int i = 0; i < intervals.length; i++) {
            // 说明这两个节点是重叠的
            if (intervals[i][0] < maxRight) {
                res++;
                maxRight = Math.min(intervals[i][1], maxRight); // 删除掉最宽的哪一个
            } else {
                maxRight = intervals[i][1];
            }
        }
        return res - 1;
    }
}

02. 划分字母区间(No. 763)

题目链接

代码随想录题解

<1> 题目

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

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s

返回一个表示每个字符串片段的长度的列表。

示例 1:

输入:s =
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”、“defegde”、“hijhklij” 。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 这样的划分是错误的,因为划分的片段数较少。

示例 2:

输入:s = “eccbbbbdec”
输出:[10]

提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成
<2> 笔记

要保证每一段中都包括一个字母的所有出现的位置,那么 划分出来这一段的终点必须要在这个字母最后出现位置或者右边;比如题目中的字符串

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果要包含所有的 a,这一段终点大于等于 a 最后出现的位置。

所以在划分的时候,一旦发现包含某个字母,那它的终点就必须在最后出现的位置的右边。

来举个例子,为了简化讲解这里举一个简单的例子

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

蓝色表示每个字母最后出现的位置。

当遍历到第一个字母 a 的时候 就决定了终点大于等于 a 最后出现的位置,题目中的下标为 8

遍历到第二个字母 b 终点要大于等于 6

继续遍历到 c 终点要大于等于 7

直到遍历到下标为 8a 的时候可以切割了,因为此时满足上面的所有条件;总结一下切割的位置,也就是此时终点的 maxRight 要等于此时节点的下标;那么对于后面的 d e f 其都符合上述条件,所以这个例子可以分为四段。

所以要通过一次遍历将所有节点的 最终位置 找出,然后逐渐遍历并且更新 maxRight 直到 maxRight == i 的时候进行切割,这就是本题的贪心策略。

<3> 代码
class Solution {
    List<Integer> res = new ArrayList<>();
    public List<Integer> partitionLabels(String s) {
        int[] hash = new int[26]; // 统计每个字符最后出现的位置
        for (int i = 0; i < s.length(); i++) {
            hash[s.charAt(i) - 97] = i;
        }
        int left = 0;
        int right = 0;
        for (int i = 0; i < s.length(); i++) {
            right = Math.max(right, hash[s.charAt(i) - 97]);
            if (i == right) {
                res.add(right - left + 1);
                left = i+1;
            }
        }
        return res;
    }
}

03. 合并区间(No. 56)

题目链接

代码随想录题解

<1> 题目

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

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104
<2> 笔记

又是一个关于区间的题目,本题和前面的思路非常类似,既然要合并所有的区间那就需要将所有可能重叠的区间聚集在一起,所以和前面相同用到排列,这里用 lambda 表达式来书写

Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));

比如说这个案例,第一段和第二段还有第三段都是重叠的,但是发现第三段到第四段没有重叠,此时就需要将前三段合并。

但与前面不同的是,此时是合并所有的重叠情况,比如说 1 与 2 和 3 都重叠,但是 2 与 3 不重叠,最终也是将这三段合并,这也就导致了,取得 right极大值

    if (intervals[i][0] > rightmostRightBound) {
    	//加入区间 并且更新start
    	res.add(new int[]{start, rightmostRightBound});
    	start = intervals[i][0];
    	rightmostRightBound = intervals[i][1];
    } else {
    	//更新最大右边界
    	rightmostRightBound = Math.max(rightmostRightBound, intervals[i][1]);
    }
<3> 代码
class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> res = new LinkedList<>();
        //按照左边界排序
        Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));
        //initial start 是最小左边界
        int start = intervals[0][0];
        int rightmostRightBound = intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            //如果左边界大于最大右边界
            if (intervals[i][0] > rightmostRightBound) {
                //加入区间 并且更新start
                res.add(new int[]{start, rightmostRightBound});
                start = intervals[i][0];
                rightmostRightBound = intervals[i][1];
            } else {
                //更新最大右边界
                rightmostRightBound = Math.max(rightmostRightBound, intervals[i][1]);
            }
        }
        res.add(new int[]{start, rightmostRightBound});
        return res.toArray(new int[res.size()][]);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/423155.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GoFrame:如何简单地搭建一个简单地微服务

一切资料来源于GoFrame官网&#xff0c; 感兴趣的&#xff0c; 可以直接去官网查阅相关资料。 首先下载框架工具&#xff0c; 下载地址&#xff1a;https://github.com/gogf/gf/releases 然后进入你想要放置的项目文件夹&#xff0c; 执行命令行 gf init {project_name} #pr…

Unity AI生成全景图制作天空盒

现在的AI很强大。 其中&#xff0c;有这样一个网站&#xff0c;通过输入提示词&#xff0c;选择某种风格就可以为你生成360全景图。 网页链接 一、生成全景图 打开网页后&#xff0c;如图&#xff1a; 勾选&#xff0c;点击CONFIRM。 点击GET STARTED&#xff0c;进入主页。…

编译链接实战(25)ThreadSanitizer检测线程安全

ThreadSanitizer&#xff08;又称为TSan&#xff09;是一个用于C/C的数据竞争检测器。在并发系统中&#xff0c;数据竞争是最常见且最难调试的错误类型之一。当两个线程并发访问同一个变量&#xff0c;并且至少有一个访问是写操作时&#xff0c;就会发生数据竞争。C11标准正式将…

XSS初级漏洞靶场

一、环境的搭建 可以在githb上找靶机包&#xff0c;使用小皮面板搭建在自己本机 与此文章类似&#xff08;放在www目录下&#xff09; 二、XSS漏洞简介 1、什么是xss漏洞 当用户访问被xss注入的网页&#xff0c;xss代码就会被提取出来。用户浏览器就会解析这段xss代码&…

每日一题 — 复写零

1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 首先找到最后一个复写的数&#xff1a; 双指针算法&#xff1a; 1、先判断 cur 位置上的值 2、然后决定 dest 移动一步还是两步 3、然后判断 dest 是否到终点了 4、最后 cur 处理越界的情况 arr[n-1] …

【C初阶】预处理

前言&#xff1a;在本文中&#xff0c;我将系统的整理一下C语言关于预处理部分的语法&#xff0c;便于整理与回归。 1.预定义符号 在C语言中&#xff0c;C标准提供里一些C预定义符号&#xff0c;在预处理期间完成&#xff0c;可以直接使用。 有如下几个符号&#xff1a; 2.#…

广搜(BFS)

在我们日常刷题的过程中&#xff0c;我们会通过遍历来获取自己想要的数组&#xff0c;搜索算法就是典型的一种。 而搜索算法中也分深搜&#xff08;DFS&#xff09;&#xff0c;广搜&#xff08;BFS&#xff09;,而今天&#xff0c;我们来说说广搜。 什么是广搜 广搜全称叫广…

SqlServer配置定时备份

在企业系统环境中&#xff0c;为了确保SQL Server数据库受到意外的人为错误、系统故障、病毒攻击等因素的影响&#xff0c;我们通常会选择定期备份数据库。但是随着时间尺度的拉长&#xff0c;如果每次备份都要去手动执行一次的话&#xff0c;可能会觉得有些麻烦&#xff0c;或…

【《高性能 MySQL》摘录】第 9 章 操作系统和硬件优化

文章目录 9.1 什么限制了MySQL的性能9.2 如何为 MySQL 选择 CPU9.2.1 哪个更好&#xff1a;更快的 CPU 还是更多的 CPU9.2.2 CPU架构9.2.3 扩展到多个CPU和核心 9.3 平衡内存和磁盘资源9.3.1 随机 I/O 和顺序 I/O9.3.2 缓存&#xff0c;读和写9.3.3 工作集是什么9.3.4 找到有效…

JMeter性能测试基本过程及示例

jmeter 为性能测试提供了一下特色&#xff1a; jmeter 可以对测试静态资源&#xff08;例如 js、html 等&#xff09;以及动态资源&#xff08;例如 php、jsp、ajax 等等&#xff09;进行性能测试 jmeter 可以挖掘出系统最大能处理的并发用户数 jmeter 提供了一系列各种形式的…

P4715 【深基16.例1】淘汰赛题解

题目 有&#xff08;n≤7&#xff09;个国家参加世界杯决赛圈且进入淘汰赛环节。已经知道各个国家的能力值&#xff0c;且都不相等。能力值高的国家和能力值低的国家踢比赛时高者获胜。1号国家和2号国家踢一场比赛&#xff0c;胜者晋级。3号国家和4号国家也踢一场&#xff0c;…

node.js最准确历史版本下载

先进入官网:Node.js https://nodejs.org/en 嫌其他博客多可以到/release下载:Node.js,在blog后面加/release https://nodejs.org/en/blog/release/ 点击next翻页,同样的道理

值得一试的五大AI编程助手

AI编程助手已成为开发过程中不可缺少的一部分&#xff0c;因为它们可以协助代码生成、理解、项目搜索以及使用提示或代码执行各种任务。甚至像谷歌Colab和Deepnote这样的云IDE平台也提供AI辅助编程&#xff0c;可以帮助您生成代码并解决问题。 本文将介绍5款值得一试的AI编程助…

外贸福利 PHP源码 WhatsApp 营销 - 批量发件人、聊天、机器人、SaaS 搭建

WhatsApp 营销工具对于外贸人员来说至关重要。随着全球贸易的不断发展&#xff0c;WhatsApp已成为了许多国际贸易商之间沟通的首选工具之一。通过利用WhatsApp营销工具&#xff0c;外贸人员可以轻松地与客户建立联系&#xff0c;传递产品信息&#xff0c;进行价格谈判&#xff…

智能分析网关V4安全帽检测/反光衣检测/通用工服检测算法及应用

TSINGSEE青犀视频智能分析网关V4内置了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为等实时检测分析&#xff0c;上报识别结果&#xff0c;并能进行语音告警播放。硬件管理平台支持RTSP、GB28181协议、以及厂家私有协议接入&#xff0c;可兼容市面上常…

【Spring Boot 3】的安全防线:整合 【Spring Security 6】

简介 Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多&#xff0c;因为相比与Sp…

巧用眼精星票证识别系统将车辆合格证快速转为结构化excel数据,简单方便

眼精星票证识别系统是一款高效且精准的OCR软件&#xff0c;它的魔力在于能将纸质文档迅速转化为电子文档&#xff0c;并实现自动化的数据结构化处理。它拥有一双"火眼金睛"&#xff0c;无论是各类发票、护照&#xff0c;还是车辆合格证等&#xff0c;都能一一识别。而…

LLC谐振变换器变频移相混合控制MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 基本控制原理 为了实现变换器较小的电压增益&#xff0c;同时又有较 高的效率&#xff0c;文中在变频控制的基础上加入移相控制&#xff0c; 在这种控制策略下&#xff0c;变换器通过调节一次侧开关管 的开关…

数据增加

目录 增加数据 实现数据增加&#xff0c;保存新的内容 注意 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 增加数据 由于 emp 表中的数据对日后的开发依然有用处&#xff0c;所以在讲解更新之前 建议将emp 表数据做一个复制。将…

【C++入门】C++关键字 | 命名空间 | C++的输入输出

目录 0.C与C 1.C的关键字 2.命名空间 2.1域 2.2C中命名冲突问题 2.3命名空间定义 2.4命名空间使用 2.5命令空间的展开&头文件的展开 3.C的输入&输出 3.1cout&cin 3.1<<流插入运算符 3.2>>流提取运算符 0.C与C C是在C的基础之上&#xff…