zoukankan      html  css  js  c++  java
  • [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));
        }
    }
    
  • 相关阅读:
    JQ轮播
    JS中正则匹配的三个方法match exec test的用法
    JavaScript 表单验证
    JS 控制CSS样式表
    AJAX 的简单用法:
    shell之运用sed将其值存到变量
    shell之创建文件及内容
    修复vbox的共享文件夹的符号链接错误
    字符转码
    php魔术方法
  • 原文地址:https://www.cnblogs.com/HoweZhan/p/12561111.html
Copyright © 2011-2022 走看看