435. 无重叠区间
题目链接:无重叠区间
题目描述:
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
解题思路:
本题和上一个射气球类似,找到重叠区间即可,将数组按左边界排序,比较当前i的左边界和上一个i的右边界,若判断重合则将两者最小有边界赋予当前i的右边界,以便确定当前重叠区域的有边界,若不重合则计数,记录不重叠区域,最后返回总区域数量减去不重叠区域数量即可。
代码实现:
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++;}}return intervals.length-count;}
}
763. 划分字母区间
题目链接:划分字母区间
题目描述:
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
解题思路:
本题比较简单,只需要记录每个字母的最后一次出现位置,只要一个字母被加入一个片段,那么这个片段的最后边界就是片段中所有字母的最后出现位置,因此可以不断更新最后出现位置,知道当前遍历位置与最大位置一致,则可切断。
代码实现:
class Solution {public List<Integer> partitionLabels(String s) {List<Integer> 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;}
}
56. 合并区间
题目链接:合并区间
题目描述:
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
解题思路:
本题和之前的重叠区间题十分相似,只不过找到重叠空间后的处理方式不同,本题是记录重叠区域的最大值,以便进行区间合并。
代码实现:
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 right = intervals[0][1];for (int i = 1; i < intervals.length; i++) {//如果左边界大于最大右边界if (intervals[i][0] > right) {//加入区间 并且更新startres.add(new int[]{start, right});start = intervals[i][0];right = intervals[i][1];} else {//更新最大右边界right= Math.max(right, intervals[i][1]);}}res.add(new int[]{start, right});return res.toArray(new int[res.size()][]);}
}