代码随想录算法训练营第36天|435. 无重叠区间,763.划分字母区间,56. 合并区间

435. 无重叠区间

力扣

思路:

1. 按左边界排序,从左到右遍历;用count记录需要移除的区间;

2. 若当前遍历区间的左边界小于前一个区间的右边界时,count++,更新当前区间右边界为作比较的这两个区间右边界的最小值;

3. 遍历结束,返回count;

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
        int count = 0;
        for(int i=1;i

思路2:

435.无重叠区间1. 按右边界从小到大排序,从左到右遍历;局部最优:遍历,留给下一个区间的空间大一些,从而尽量避免交叉。全局最优:选取最多的非交叉区间。

2. 用edge表示分割线(右边界),初始化为Integer.MIN_VALUE。若当前遍历区间左边界<分割线,说明有交集,count++;若当前遍历区间左边界>=分割线,说明无交集,更新分割线为当前遍历区间的右边界;

3. 遍历结束,返回count。

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals,(a,b)->Integer.compare(a[1],b[1]));
        int count = 0;
        int edge = Integer.MIN_VALUE;
        for(int i=0;i

763.划分字母区间

力扣

思路:

1. 统计每个字母最后出现的位置;

2. 从头遍历字符,并更新字符的最远出现位置下标;若最远出现位置下标与当前下标相等,则找到了分割点。

763.划分字母区间

class Solution {
    public List partitionLabels(String s) {
        List res = new LinkedList<>();
        int[] edge = new int[26];
        char[] chars = s.toCharArray();
        for(int i=0;i

思路2:无重叠区间

1. 统计字符串中所有字符的起始和结束位置,记录为区间;

2. 按照左边界从小到大排序,找到边界将区间划分互不重叠的组;

3. 返回边界合集;

class Solution {
    public List partitionLabels(String s) {
        List res = new ArrayList<>();
        int[][] partitions = findPartitions(s);
        Arrays.sort(partitions,(o1,o2)->Integer.compare(o1[0],o2[0]));
        int right = partitions[0][1];//记录最大右边界
        int left = 0;
        for(int i=0;iright){//分割
                res.add(right-left+1);
                left = partitions[i][0];
            }
            right = Math.max(right,partitions[i][1]);
        }
        res.add(right-left+1);
        return res;
    }
    public int[][] findPartitions(String s){
        //记录各个字母左右边界
        int[][] hash = new int[26][2];
        for(int i=0;i temp = new ArrayList<>();
        List> h = new LinkedList<>();
        for(int i=0;i<26;i++){
            temp.clear();
            temp.add(hash[i][0]);
            temp.add(hash[i][1]);
            h.add(new ArrayList<>(temp));
        }
        int[][] res = new int[h.size()][2];
        for(int i=0;i list = h.get(i);
            res[i][0] = list.get(0);
            res[i][1] = list.get(1);
        }
        return res;
    }
}

56. 合并区间

力扣

思路:

1. 按照左边界从小到大排序;

2. 局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间;整体最优:合并所有重叠的区间;

3. 遍历区间;若当前所遍历的区间的左边界小于等于前一个区间的右边界,合并为一个新区间,加入result数组;若没有合并,则将原数组加入result数组。

class Solution {
    public int[][] merge(int[][] intervals) {
        LinkedList res = new LinkedList<>();
        Arrays.sort(intervals,(o1,o2)->Integer.compare(o1[0],o2[0]));
        res.add(intervals[0]);
        for(int i=1;i

你可能感兴趣的:(leetcode,算法)