[dp/贪心]435. 无重叠区间-----经典问题

在这里插入图片描述
无重叠区间是一类十分经典的问题,很多问题的模型就是基于这一就无重叠区间问题的。

首先,一个很直接的思路就是这类题目和LIS(最长上升子序列问题)很像。
所以考虑使用动态规划来解这道题

import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if(intervals.length == 0) return 0 ;
        Arrays.sort(intervals, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                if (a[1] < b[1])
                    return a[1] - b[1];
                return a[0] - b[0];
            }
        });
        int n = intervals.length;
        int[] dp = new int[n];
       
        dp[0] = 1;//基本问题的解,就是只选自己
        
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (intervals[i][0] >= intervals[j][1] && dp[i] < 1 + dp[j]) {
                    dp[i] = dp[j] + 1;
                }
            }
        }
        //和LIS问题一样一定是返回dp数组中的最大值,而不是dp[n-1]
        int res = 0;
        for (int i = 0; i < n; i++) {
            res = Math.max(res,dp[i]);
        }
        return n - res;
    }

    public static void main(String[] args) {
        int[][] ins = {{1, 2}, {2,3}};
        System.out.println(new Solution().eraseOverlapIntervals(ins));
    }
}

其实这类问题可以使用贪心算法来解决,证明的方法是使用反证法.

贪心策略:每次选择最快结束的区间,留给更多的空间给后续的区间
!](https://img-blog.csdnimg.cn/20200324190654294.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2lkZWZpbmVk,size_16,color_FFFFFF,t_70)

import java.util.Arrays;

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) return 0;
        Arrays.sort(intervals, (a, b) -> {
            if (a[1] != b[1])
                return a[1] - b[1];
            return a[0] - b[0];
        });
        for (int i = 0; i < intervals.length; i++) {
            for (int j = 0; j < intervals[0].length; j++) {
                System.out.print(intervals[i][j]);
            }
            System.out.println();
        }
        int res = 1;
        int end = intervals[0][1];//选择第一个区间的末端
        //每次选择区间结尾最小的
        for (int i = 0; i < intervals.length; i++) {
            if(end <= intervals[i][0]){
                res++;
                end = intervals[i][1];
            }
        }
        return intervals.length - res;
    }

    public static void main(String[] args) {
        int[][] ins = {{1, 2}, {3, 5}, {2, 6}};
        System.out.println(new Solution().eraseOverlapIntervals(ins));
    }
}
原文地址:https://www.cnblogs.com/HoweZhan/p/12561111.html