435. 无重叠区间
给定一个区间的集合
intervals
,其中intervals[i] = [starti, endi]
。返回需要移除区间的最小数量,使剩余区间互不重叠 。
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
这道题需要我们求重叠区间,然后记录重叠区间就可以了
解题思路:
- 设置count用来记录重叠区间
- 将数组按照左边从小到大进行排序
- 如果
intervals[i][0]<intervals[i-1][1]
说明i数组和i-1数组重叠,将count++
记录重叠区间,然后保留最小右边界
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
int count=0;
Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
for(int i=1;i<intervals.length;i++){
if(intervals[i][0]<intervals[i-1][1]){ //重叠情况
count++;
intervals[i][1]=Math.min(intervals[i][1],intervals[i-1][1]);
}
}
return count;
}
}
763. 划分字母区间
给你一个字符串
s
。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是
s
。返回一个表示每个字符串片段的长度的列表。
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。
这道题的关键是找到分割点
解题思路:
- 设置一个长度为27的数组,26个字母
- 遍历字符串,将每个字符最后出现的位置记录到数组当中
hash[s.charAt(i)-'a']=i;
- 字母的最远下标就是分割点,可以记录下来,并需要一个left结点定义开始分割的起点
right=Math.max(right,hash[s.charAt(i)-'a']);
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> reslut=new ArrayList<>();
int[] hash=new int[27];
//将每个字符最后出现的位置
for(int i=0;i<s.length();i++){
hash[s.charAt(i)-'a']=i;
}
int left=0;
int right=0;
for(int i=0;i<s.length();i++){
right=Math.max(right,hash[s.charAt(i)-'a']);
if(i==right){ //找到分割点
reslut.add(right-left+1);
left=i+1;
}
}
return reslut;
}
}
56. 合并区间
以数组
intervals
表示若干个区间的集合,其中单个区间为intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
这道题的思路比较简单,就是需要找到重叠区间,然后将前一个区间的左区间,后后一个区间的右区间相连接构成结果,但是实际操作起来还是有些许复杂。
解题思路:
-
定义一个list用来添加结果,后续还需要转换成int[][]输出
-
将数组按照左边从小到大排序
-
定义左边界和右边界,之后循环就可以从1开始
-
遍历数组
如果发现数组是重合的即
intervals[i][0]≤intervals[i-1][1]
我们需要去更新最大的右边界right=Math.max(right,intervals[i][1]);
如果发现数组接下来是不重叠,我们需要将前面求出的最小左边界和最大右边界添加到结果当中
然后更新左边界和右边界
-
将剩余的数组添加到结果当中
-
最后需要将list转换为数组进行返回
reslut.toArray(new int[reslut.size()][]);
class Solution {
public int[][] merge(int[][] intervals) {
List<int[]> reslut=new ArrayList<>();
//排序
Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
int start=intervals[0][0]; //左边界
int right=intervals[0][1]; //右边界
for(int i=1;i<intervals.length;i++){
if(intervals[i][0]>right){ //返现区间没有继续重叠相连
reslut.add(new int[]{start,right}); //按照最大左边界和右边界将其添加到结果中
start=intervals[i][0]; //更新左边界和右边界
right=intervals[i][1];
}else{ //发现区间重合去更新最大右边界
right=Math.max(right,intervals[i][1]);
}
}
reslut.add(new int[]{start,right}); //把最后剩余的添加进来
return reslut.toArray(new int[reslut.size()][]);
}
}