435. 无重叠区间
本题其实和452. 用最少数量的箭引爆气球非常像,按区间头进行排序的话,弓箭的数量就相当于是交叉区间的数量,只要把弓箭那道题目代码里射爆气球的判断条件去掉等号(认为[0, 1][1, 2]不是相邻区间),然后用总区间数减去弓箭数量就是要移除的区间数量了。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
LinkedList<int[]> li = new LinkedList<>();
li.add(intervals[0]);
for(int i = 1; i < intervals.length; i++){
int[] curr = intervals[i];
int[] last = li.getLast();
if(last[1] > curr[0]){
last[1] = Math.min(last[1], curr[1]);
}
else{
li.add(curr);
}
}
return intervals.length - li.size();
}
}
763. 划分字母区间
题目要做的是,把s尽可能多地划分。同时有一个要求就是同一个字母,最多只能出现在其中一个片段中。
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> res = new ArrayList<>();
int[] edge = new int[26]; // 题目规定s仅由小写字母组成,可用长为26的数组替代哈希表,记录s中每个字母最后出现的索引
for(int i = 0; i < s.length(); i++){
edge[s.charAt(i) - 'a'] = i;
}
int index = 0;
int lastEdge = -1;
for(int i = 0; i < s.length(); i++){
index = Math.max(index, edge[s.charAt(i) - 'a']);
if(i == index){
res.add(i - lastEdge);
lastEdge = i;
}
}
return res;
}
}
56. 合并区间
合并区间是如果有多个区间重合在一起可以合并为同一个区间,所以按区间头排序后,合并后的区间尾应当是最尾的区间尾。这一点和“用最少箭引爆气球”等求区间的重叠数有所不同。
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
LinkedList<int[]> li = new LinkedList<>();
li.add(intervals[0]);
for(int i = 1; i < intervals.length; i++){
int[] curr = intervals[i];
int[] last = li.getLast();
if(curr[0] <= last[1]){
last[1] = Math.max(curr[1], last[1]);
continue;
}
else{
li.add(curr);
}
}
return li.toArray(new int[li.size()][]);
}
}