Leetcode 435.无重叠区间
题目:435.无重叠区间
初始思路
代码
var eraseOverlapIntervals = function (intervals) {// 按照右边界从小到大排序intervals.sort((a, b) => {return a[1] - b[1]})// 记录非交叉区间的个数let count = 1// 记录区间分割点let end = intervals[0][1]for (let i = 1; i < intervals.length; i++){let temp = intervals[i]if (temp[0] >= end) {// 如果区间不交叉更新分割点end = temp[1]count++}}// 区间总数减去非交叉区间就是需要移除的区间个数return intervals.length - count};
感想
- 按照右边界排序,就要从左向右遍历,因为右边界越小越好,只要右边界越小,留给下一个区间的空间就越大,所以从左向右遍历,优先选右边界小的。
- 按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了。

Leetcode 763.划分字母区间
题目:763.划分字母区间
初始思路
找最远下标可以用lastIndexOf,不停遍历更新也可以。
代码
var partitionLabels = function (s) {let hash = {}for (let i = 0; i < s.length; i++){// 获得最远下标hash[s[i]] = i}let res = []let left = 0let right = 0for (let i = 0; i < s.length; i++){// 当前右区间和最远下标作比较right = Math.max(right, hash[s[i]])// 如果右区间到了最远坐标就可以分割了if (right === i) {// 加入这段区间的长度res.push(right - left + 1)// 开始下一段区间的寻找left = i + 1}}return res};
感想
- 在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

Leetcode 56.合并区间
题目:56.合并区间
初始思路
代码
var merge = function (intervals) {// 按照左边界从小到大排序intervals.sort((a, b) => {return a[0] - b[0]})let prev = intervals[0]let res = []for (let i = 0; i < intervals.length; i++){let temp = intervals[i]if (temp[0] > prev[1]) {// 如果区间不重叠,直接把前一个区间加进去res.push(prev)// 进入下一个区间开始比较prev = temp} else {// 如果重叠的话,右区间取两者最大值prev[1] = Math.max(temp[1], prev[1])}}// 加入最后一个区间res.push(prev)return res};
感想
- 按照左边界排序,排序之后局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间了,整体最优:合并所有重叠的区间。
- 按照左边界从小到大排序之后,如果 intervals[i][0] < intervals[i - 1][1] 即intervals[i]左边界 < intervals[i - 1]右边界,则一定有重复,因为intervals[i]的左边界一定是大于等于intervals[i - 1]的左边界。
- 即:intervals[i]的左边界在intervals[i - 1]左边界和右边界的范围内,那么一定有重复!

