435. 无重叠区间
完成
思路:
本题的贪心策略是,把区间按左端从小到大排序,当碰到重叠区间时,优先去掉右端更大的,减少后续重叠的可能。也可以理解为优先保留跨度更小的区间,跨度小的区间和其他区间重叠的可能性就小。
代码
class Solution {public int eraseOverlapIntervals(int[][] intervals) {int res = 0;Arrays.sort(intervals, (a,b)->a[0]==b[0]?a[1]-b[1]:a[0]-b[0]);int end = intervals[0][1];for (int i = 1; i < intervals.length; i++) {if(intervals[i][0]<end){ // 重叠res++;// 这里取二者之小 就是保留右端更小的区间,即跨度小的区间end = Math.min(end, intervals[i][1]);}else end = intervals[i][1];}return res;}
}
763.划分字母区间
完成
思路:
遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点。
代码
class Solution {public List<Integer> partitionLabels(String s) {List<Integer> res = new ArrayList<>();// 统计每个字符出现的最远位置int[] nums = new int[26];for (int i = 0; i < s.length(); i++) {nums[s.charAt(i)-'a'] = i;}int left = 0;int right = 0;// 遍历字符串,更新每组的最远位置for (int i = 0; i < s.length(); i++) {right = Math.max(right, nums[s.charAt(i)-'a']);if(i==right){ // 做分割res.add(right-left+1);left = i+1;}}return res;}
}
56. 合并区间
完成
代码
重叠区间问题,思路是一样的
class Solution {public int[][] merge(int[][] intervals) {List<int[]> res = new ArrayList<>();Arrays.sort(intervals,(a,b)->a[0]-b[0]);res.add(intervals[0]);for (int i = 1; i < intervals.length; i++) {// 重叠if(intervals[i][0]<=res.getLast()[1]){// 构造新的区间范围int start = res.getLast()[0];int end = Math.max(intervals[i][1], res.getLast()[1]);res.removeLast();res.add(new int[]{start,end});}else{res.add(intervals[i]);}}return res.toArray(new int[res.size()][]);}
}
下面的代码在合并区间时不涉及出队入队,稍快一些
class Solution {public int[][] merge(int[][] intervals) {List<int[]> res = new ArrayList<>();Arrays.sort(intervals,(a,b)->a[0]-b[0]);int left = intervals[0][0];int right = intervals[0][1];for (int i = 1; i < intervals.length; i++) {if(intervals[i][0]<=right){right = Math.max(right, intervals[i][1]);}else{res.add(new int[]{left,right});left = intervals[i][0];right = intervals[i][1];}}// 需要额外添加最后一个区间res.add(new int[]{left,right});return res.toArray(new int[res.size()][]);}
}