题目链接:435. 无重叠区间
大佬视频讲解:无重叠区间视频讲解
和昨日的最少箭扎气球有些类似,先按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了
首先区间1,2,3,4,5,6都按照右边界排好序。

取 区间1 右边界a和 区间2左边界b,如果区间a>b时,说明区间交叉,需要删除一个重叠区间,重新找右边界,取区间a和b中的最小右边界,继续往后遍历。若a
总共区间个数为5,减去非交叉区间的个数3,移除区间的最小数量就是2。
- class Solution {
- public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, (a,b)-> {//按右边界排序
- return Integer.compare(a[0],b[0]);
- });
-
- int count = 1;
- for(int i = 1;i < intervals.length;i++){
- if(intervals[i][0] < intervals[i-1][1]){
- intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]);//选择小的右边
- continue;
- }else{
- count++;//非交叉区间数加1
- }
- }
-
- return intervals.length - count;//需要删除的区间数
- }
- }
时间复杂度:O(n logN);(排序数组)
空间复杂度:O( logN);(java所使用的内置函数用的是快速排序需要 logN 的空间)
题目链接:763.划分字母区间
大佬视频讲解:划分字母区间视频讲解
这道题有些技巧,但这个技巧我不知道...
在遍历的过程中相当于是要找每一个字母的边界,当找到之前遍历过的所有字母的最远边界,也就找到了分割点。此时前面出现过所有字母,最远也就到这个边界了。
所以步骤为

- class Solution {
- public List
partitionLabels(String S) { - List
list = new LinkedList<>(); - int[] edge = new int[26];//边界数组
- char[] chars = S.toCharArray();//字符串转字符串数组
-
- for (int i = 0; i < chars.length; i++) {//更新字母的最远边界
- edge[chars[i] - 'a'] = i;
- }
-
- int idx = 0;
- int last = -1;
- for (int i = 0; i < chars.length; i++) {//遍历数组
- idx = Math.max(idx,edge[chars[i] - 'a']);
- if (i == idx) {//找到最远边界后分割,收集字符串长度
- list.add(i - last);
- last = i;
- }
- }
- return list;
- }
- }
时间复杂度:O(n );(遍历数组)
空间复杂度:O(1);(hash数组是固定大小)
题目链接:56. 合并区间
大佬视频讲解:合并区间视频讲解
这道题和无重叠区间,最少箭射气球 ,都是判断区间重叠。区别就是判断区间重叠后的逻辑,这道题是判断区间重叠后要进行区间合并,因此还是贪心,先排序再处理。
先拿题目例子画个图 intervals = [[1,3],[2,6],[8,10],[15,18]]

先按照左边界从小到大排序,然后如果
intervals[i][0] <= intervals[i - 1][1]即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重爹,所以是<=)将重叠区间合并,合并后取最小左边界和最大右边界,作为一个新的区间,加入到result数组。如果没有合并就把原区间加入到result数组。
-
- class Solution {
- public int[][] merge(int[][] intervals) {
- List<int[]> res = new LinkedList<>();
- Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));//按照左边界排序
-
- int start = intervals[0][0];//最小左边界
- int rightmost= intervals[0][1];//最大右边界
-
- for (int i = 1; i < intervals.length; i++) {
- //如果左边界大于最大右边界
- if (intervals[i][0] > rightmost) {
-
- res.add(new int[]{start, rightmost});//加入区间
- start = intervals[i][0];//更新start
- rightmost= intervals[i][1];
- } else {
-
- rightmost= Math.max(rightmost, intervals[i][1]);//更新最大右边界
- }
- }
-
- res.add(new int[]{start, rightmost});
- return res.toArray(new int[res.size()][]);
- }
- }
时间复杂度:O(n logN);(排序数组)
空间复杂度:O( logN);(java所使用的内置函数用的是快速排序需要 logN 的空间)
以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网