随想录Day36 | 435. 无重叠区间、763. 划分字母区间、6. 合并区间 | 贪心

153 阅读1分钟

435. 无重叠区间

题目链接:435. 无重叠区间

思路: 区间调度问题思路可以分为以下三步:

1、从区间集合 intvs 中选择一个区间 x,这个 x 是在当前所有区间中结束最早的end 最小)。

2、把所有与 x 区间相交的区间从区间集合 intvs 中删除。

3、重复步骤 1 和 2,直到 intvs 为空为止。之前选出的那些 x 就是最大不相交子集

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        int n = intervals.length;
        return n - intervalSchedule(intervals);
    }

    int intervalSchedule(int[][] intvs) {
        Arrays.sort(intvs, (a, b) -> {
            return a[1] - b[1];
        });
        int count = 1;
        int end = intvs[0][1];
        for (int[] intv : intvs) {
            int start = intv[0];
            if (start >= end) {
                count++;
                end = intv[1];
            }
        }
        return count;
    }
}

763. 划分字母区间

题目链接:763. 划分字母区间

思路: 在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

可以分为如下两步:

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
class Solution {
    public List<Integer> partitionLabels(String s) {
        List<Integer> res = new LinkedList<>();
        int[] edge = new int[26];
        char[] ch = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            edge[ch[i] - 'a'] = i;
        }
        int index = 0;
        int last = -1;
        for (int i = 0; i < s.length(); i++) {
            index = Math.max(index, edge[ch[i] - 'a']);
            if (i == index) {
                res.add(i - last);
                last = i;
            }
        }
        return res;
    }
}

6. 合并区间

题目链接:6. 合并区间

思路: 先按区间的 start 排序,对于几个相交区间合并后的结果区间 xx.start 一定是这些相交区间中 start 最小的,x.end 一定是这些相交区间中 end 最大的。由于已经排了序,x.start 很好确定,求 x.end 也很容易,可以类比在数组中找最大值的过程。

class Solution {
    public int[][] merge(int[][] intervals) {
        LinkedList<int[]> res = new LinkedList<>();
        Arrays.sort(intervals, (a, b) -> {
            return a[0] - b[0];
        });

        res.add(intervals[0]);

        for (int[] intv : intervals) {
            int[] last = res.getLast();
            if (intv[0] <= last[1]) {
                last[1] = Math.max(intv[1], last[1]);
            } else {
                res.add(new int[]{intv[0], intv[1]});
            }
        }

        return res.toArray(new int[0][0]);
    }
}