仅为个人记录复盘学习历程,解题思路来自代码随想录
代码随想录刷题笔记总结网址:
代码随想录
435. 无重叠区间
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
即问题是:保证剩余区间不重叠的前提下,移走最少区间的数量
关键思路:
对所有区间进行排序,按顺序遍历,记录所有不重叠的区间个数,
总区间个数-不重叠区间个数=需要移除区间个数
不重叠区间个数越多,需要移除的区间就越少
几个比较重要的问题:
1.如何寻找统计不重叠区间?
排序的区间中,后面的左边界小于前面的右边界则说明区间重叠,
如果区间重叠,则更新后面的右边界为左右两个区间右边界中更小的那一个,
如果区间不重叠,则发现了不重叠区间,计数加一,
最后的计数就是不重叠区间的计数
2.当判断区间1和区间2重叠后,如何判断区间3是否和区间1,2重叠?
假设区间1,2重叠,则将区间1,2中更小的右边界和区间3的左边界判断,如果区间1,2中更小的右边界和区间3的左边界交叉,则说明三个区间重叠
3.如何保证不重叠区间最多?
把重叠的全部移走后不多余移走剩下非重叠的就是保证了不重叠区间最多,而移走的重叠区间最少
代码大致如下:
public int eraseOverlapIntervals(int[][] intervals) {
//对数组区间进行排序
Arrays.sort(intervals,(a,b)->{return Integer.compare(a[1],b[1]);});
//初始化不重叠区间数量
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]);
}
else{
count++;
}
}
return intervals.length-count;
}
763.划分字母区间
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,
片段满足如下要求:
同一字母最多出现在一个片段中
最后需要返回一个表示每个字符串片段的长度的列表
关键思路:
要想实现题目要求,其实就是要找到一个切割点,在该切割点前所有字母都到达了它能到达的最远距离。需要做的就是:
1.统计每个字母所能到达的最远距离
2.当遍历字符串所有的组成字符时,一边遍历,一边更新应该到达的最远距离,
当 当前距离=应该到达的最远距离 时,说明到达了一个切割点,找到了一个片段,
找到所有片段只需要遍历完所有的组成字符
代码大致如下:
public List<Integer> partitionLabels(String s) {
//初始化数据
List<Integer>res=new ArrayList<>();
char[]chars=s.toCharArray();
int []count=new int[26];
//遍历组成字符数组,寻找每个字符出现的最远位置
for(int i=0;i<chars.length;i++){
count[chars[i]-'a']=i;
}
//分割字符串
int start=-1;
int end=0;
for(int i=0;i<chars.length;i++){
end=Math.max(end,count[chars[i]-'a']);
if(i==end){
//加入片段长度
res.add(end-start);
//更新片段开头
start=i;
}
}
return res;
}