【前端er每日算法】贪心算法--区间三题

101 阅读1分钟

题目一 435. 无重叠区间

思路

这个题和上一个题 452. 用最少数量的箭引爆气球 思路比较类似,区间按照起始点排序,然后遍历区间,从第一个函数,如果区间的开始点比上一个区间的终点小,说明两个区间重叠了,需要删除一个,然后将该区间的终点更新为这两个区间的最小值。

/**
 * @param {number[][]} intervals
 * @return {number}
 */
var eraseOverlapIntervals = function(intervals) {
    let count = 0;
    intervals.sort((a, b) => a[0] - b[0]);
    for (let i = 1; i < intervals.length; i++) {
        // 区间重叠
        if (intervals[i][0] < intervals[i - 1][1]) {
            count++;
            intervals[i][1] = Math.min(intervals[i][1], intervals[i-1][1]);
        }
    }
    return count;
};

题目二 763. 划分字母区间

思路

首先将所有的字母的最长索引的hash记录下来,然后如果遍历字符串,记录之前已经遍历过的字符的最远边界,如果索引和最远边界相等了,说明找到这个区间了,将这个长度记录下来。

var partitionLabels = function(str) {
    let result = [];
    let hash = {};
    let len = str.length;
    for (let i = 0; i < len; i++) {
        hash[str[i]] = i;
    }
    let start = 0;
    let right = 0;
    for (let i = 0; i < len; i++) {
        // 这里是已出现字母的最远边界
        right = Math.max(right, hash[str[i]]);
        if (i === right) {
            result.push(i - start + 1);
            start = i + 1;
        }
    }
    return result;
};

题目三 56. 合并区间

思路

  • 按照起始点排序数组
  • 将第一个区间放到结果里
  • 从索引1开始遍历数组,拿到result中最后一个元素的终点,如果当前区间的起始点小于这个终点,说明重叠了,进行区间合并,更新result的终点为当前区间和之前终点的最大值,如果没有重叠,则加到result数组里。
var merge = function(intervals) {
    let result = [];
    intervals.sort((a, b) => a[0] - b[0]);
    result.push(intervals[0]);
    let len = intervals.length;
    for (let i = 1; i < len; i++) {
        right = result[result.length - 1][1];
        if (intervals[i][0] <= right) {
            let max = Math.max(right, intervals[i][1]);
            result[result.length - 1][1] = max;
        } else {
            result.push(intervals[i]);
        }
    }
    return result;
};