leetcode记录-435-无重叠区间-贪心

435.无重叠区间

leetcode记录-435-无重叠区间-贪心_第1张图片

思路

  1. 自己的:自己的思路是,遍历每个元素,对于i对应的元素,如果比j对应的首元素小,当i尾>j首且i尾=j尾,去掉区间i。每个区间与其他所有的比较。—— 思路上可行,但是要注意,应该要按照首元素排序,否则可能因为第一个元素起点过大导致结果不同。
  2. 题解的:
    ①元素按照首元素排序,然后从第一个元素开始,让end标志为其尾巴,如果后面的元素头>=end,证明没有相交,且因为按头排序的,所以一个一个比较遇到的正好是第一个满足这种情况的元素,他为下一个不相交区间,end为他的尾巴;如果后面的元素头 ②元素按照尾元素排序,每次尽可能选择尾巴小的。让end为第一个的尾巴,后面的元素,如果头>end,end就为他的尾;如果不是,end不变,因为相交的尾巴肯定比end大,秉承偏好尾巴小,我们直接去掉区间数+1即可。

代码

  1. 自己的(虽然没通过全部用例)
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
       Arrays.sort(intervals,((o1, o2) -> (o1[0]-o2[0])));
        int[] a = new int[intervals.length];
        int flag = 0;
        for (int i = 0; i < intervals.length; i++) {
            for (int j = 0; j<intervals.length; j++) {
                if (j != i &&intervals[i][0]<=intervals[j][0] && a[j]==0 && a[i]==0){
                    if (intervals[i][1]>intervals[j][0] && intervals[i][1]<intervals[j][1]){
                        a[j]=1;
                        flag++;
                        System.out.println(Arrays.toString(intervals[j]));
                    }else if (intervals[i][1]>intervals[j][0] && intervals[i][1]>=intervals[j][1]){
                        a[i]=1;
                        flag++;
                        System.out.println(Arrays.toString(intervals[i]));
                        break;
                    }
                }
            }
        }
        return flag;
    }
}

在这里插入图片描述
这个用例一眼望不到边,但是能到55证明方法可行,只是太笨了。
2. 排序首元素

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
       Arrays.sort(intervals,(o1, o2) -> (o1[0]-o2[0]));
        int end = intervals[0][1];
        int flag = 0;
        for (int i = 1; i < intervals.length; i++) {
            if(end<=intervals[i][0])
                end=intervals[i][1];
            else {
                end=Math.min(end,intervals[i][1]);
                flag++;
            }
        }
        return flag;
    }
}
  1. 排序尾元素
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
       Arrays.sort(intervals,(o1, o2) -> (o1[1]-o2[1]));
        int flag=0;
        int end=intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            if (end<=intervals[i][0])
                end=intervals[i][1];
            else
                flag++;
        }
        return flag;
    }
}

技巧

  1. 数组排序:
    ①升序排一维:Arrays.sort(ints);
    ②升序排一维部分:Arrays.sort(ints, 2, 5);
    ③升序排二维某个下标:Arrays.sort(ints,(o1, o2) -> (o1[1]-o2[1])); 其中[1]指的是下标,按照自己想要的替换。
  2. 时间范围、区间调度等可参考,且题目需要两个方向考虑时思考能否一个方向贪心(从左到右满足某个条件+从右往左满足另一个,某边满足某个条件即可等)。
  3. flag设为初始值,在循环中根据条件flag变更值。

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