LeetCode刷题 Day36

79 阅读1分钟

LeetCode刷题 Day36

435. Non-overlapping Intervals

Given an array of intervals intervals where intervals[i] = [starti, endi], return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.

Example 1:

Input: intervals = [[1,2],[2,3],[3,4],[1,3]]
Output: 1
Explanation: [1,3] can be removed and the rest of the intervals are non-overlapping.

Example 2:

Input: intervals = [[1,2],[1,2],[1,2]]
Output: 2
Explanation: You need to remove two [1,2] to make the rest of the intervals non-overlapping.

Example 3:

Input: intervals = [[1,2],[2,3]]
Output: 0
Explanation: You don't need to remove any of the intervals since they're already non-overlapping.

思路: 和射气球的问题类似

  • 首先按照item[0]排序, 当有overlap的时候,res++ 同时找到overlap中最小的item[1]来模拟删除过程

代码:

var eraseOverlapIntervals = function(intervals) {
    intervals.sort((a, b) => a[0] - b[0]);
    let res = 0;
    for (let i = 1; i < intervals.length; i++) {
        if (intervals[i][0] < intervals[i - 1][1]) {
            res++;
            intervals[i][1] = Math.min(intervals[i][1], intervals[i - 1][1]);
        }         
    }

    return res;
};

时间复杂度: O(nlogn) 空间复杂度: O(1)


763. Partition Labels

You are given a string s. We want to partition the string into as many parts as possible so that each letter appears in at most one part.

Note that the partition is done so that after concatenating all the parts in order, the resultant string should be s.

Return a list of integers representing the size of these parts.

Example 1:

Input: s = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
This is a partition so that each letter appears in at most one part.
A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits s into less parts.

Example 2:

Input: s = "eccbbbbdec"
Output: [10]

思路: 难点在于如何找到分割点,可以分为两步

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

代码:

var partitionLabels = function(s) {
    let cache = {};
    let res = [];
    for (let i = 0; i < s.length; i++) {
        cache[s[i]] = i;
    }
    
    let left = 0;
    let right = 0;
    
    for (let i = 0; i < s.length; i++) {
        right = Math.max(right, cache[s[i]]);
        if (i === right) {
            res.push(right - left + 1);
            left = i + 1;
        }
    }

    return res;
};

时间复杂度: O(n) 空间复杂度: O(n)


56. Merge Intervals

Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.

 Example 1:

Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6].

Example 2:

Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.

思路:

  • 分别提取intervals[0], intervals[1] push到starts, ends数组中
  • 排序 starts, ends
  • init一个slow pointer
  • 当 starts[i] <= ends[i - 1]时,跳过循环
  • 当 starts[i] > ends[i - 1]时,res.push(starts[slow], ends[i - 1]), slow = i;

代码:

var merge = function(intervals) {
    let starts = [];
    let ends = [];
    let slow = 0;
    let res = [];
    
    for (let interval of intervals) {
        starts.push(interval[0]);
        ends.push(interval[1]);
    }

    starts.sort((a, b) => a -  b);
    ends.sort((a, b) => a -  b);

    for (let i = 1; i < starts.length; i++) {
        if (starts[i] <= ends[i - 1]) continue;
        else {
            res.push([starts[slow], ends[i - 1]]);
            slow = i;
        }
    }
    res.push([starts[slow], ends[ends.length - 1]])
    return res;
};

时间复杂度: O(nlogn) 空间复杂度: O(n)