LeetCode:435. 无重叠区间 - 力扣(LeetCode)
1.思路
将重叠区间进行排序,Java8新特性,定义一个计数器和数据段的前驱有边界,将当前元素左边界与前驱节点右边界进行比较。如果当前节点左边界小于前驱线段右边界,说明两者之间有交叉,计数器+1,更新pre为两者的较小值(相当于删除了右边界较大的值)。而如果当前节点的左边界大于等于前驱线段的右边界,则更新pre为当前节点的右边界,依次循环进行。
2.代码实现
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
// 排序
Arrays.sort(intervals, (a, b) -> {
return Integer.compare(a[0], b[0]);
});
// 计数器,移除的最小数量
int count = 0;
// 移除右侧区间较远的那个
int pre = intervals[0][1];
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < pre) {
count++;
pre = Math.min(pre, intervals[i][1]); // 更新pre为两者之间的较小值,相当于删除了较大值
} else {
pre = intervals[i][1]; // 更新pre
}
}
return count;
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(1).
LeetCode:
1.思路
遍历更新获取字符串中每个字符出现的最远位置,遍历更新获取子串左右位置,获取相应的子串长度加入结果集中。
2.代码实现
class Solution {
public List<Integer> partitionLabels(String s) {
// 结果集
List<Integer> result = new LinkedList<>();
// 26个英文字母输入???
int[] edge = new int[26];
char[] chars = s.toCharArray();
// 遍历,更新与当前元素的最远索引
for (int i = 0; i < chars.length; i++) {
edge[chars[i] - 'a'] = i;
}
int left = 0; // 当前字符串的起始位置
int right = 0; // 当前字符串的最远位置
for (int i = 0; i < chars.length; i++) {
right = Math.max(right, edge[chars[i] - 'a']); // 更新当前子串的最远位置
if (i == right) {
result.add(i - left + 1);
left = i + 1; // 更新左边界
}
}
return result;
}
}
3.复杂度分析
时间复杂度:O(nlogn).
空间复杂度:O(n).
LeetCode:class Solution {
public int[][] merge(int[][] intervals) {
// 结果集
List<int[]> result = new ArrayList<>();
// 对区间进行排序
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
// 前驱节点
int preLeft = intervals[0][0];
int preRight = intervals[0][1];
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] <= preRight) { // 如果有重叠区间,更新有边界为两者之间的较大值
preRight = Math.max(preRight, intervals[i][1]);
} else {
// 当前索引左侧值大于前一线段右侧值,无重叠区间,直接加入结果集
result.add(new int[]{preLeft, preRight});
preLeft = intervals[i][0];
preRight = intervals[i][1];
}
}
// 将最后一段加入到结果集
result.add(new int[]{preLeft, preRight});
// 将结果集转化为数组
return result.toArray(new int[result.size()][]);
}
}
1.思路
创建结果集收集无重叠数组,对区间进行左边界排序,设定前驱左右节点值,对数组进行遍历(更新前驱数组左右边界值)当前数组左值大于前一数组右值时,说明无重叠加入结果集,当前数组左值小于等于前一数组右值时,有重叠,更新数组右边界为两者之间的较大值。记得将最后一段数组加入结果集中,将结果集转为二维数组返回即可。
2.代码实现
class Solution {
public int[][] merge(int[][] intervals) {
// 结果集
List<int[]> result = new ArrayList<>();
// 对区间进行排序
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
// 前驱节点
int preLeft = intervals[0][0];
int preRight = intervals[0][1];
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] <= preRight) { // 如果有重叠区间,更新有边界为两者之间的较大值
preRight = Math.max(preRight, intervals[i][1]);
} else {
// 当前索引左侧值大于前一线段右侧值,无重叠区间,直接加入结果集
result.add(new int[]{preLeft, preRight});
preLeft = intervals[i][0];
preRight = intervals[i][1];
}
}
// 将最后一段加入到结果集
result.add(new int[]{preLeft, preRight});
// 将结果集转化为数组
return result.toArray(new int[result.size()][]);
}
}
3.复杂度分析
时间复杂度:O(nlogn).排序需要的时间开销
空间复杂度:O(logn).// 排序需要的空间开销