本文共 2072 字,大约阅读时间需要 6 分钟。
区间调度问题是一个经典的贪心问题,目标是从给定的区间中选择尽可能多的不相交的区间。可以使用贪心算法或动态规划来解决。
这种方法的时间复杂度是 (O(n \log n)),主要来自于排序的步骤。
f
,其中 f[i]
表示前 i
个区间中最优解的最大数量。f[0]
初始化为 1,因为至少有一个区间。i
,找到最大的 j
,使得 j
不与区间 i
重叠,然后 f[i] = f[j] + 1
。f[n-1]
即为最大区间数量。这种方法的时间复杂度是 (O(n^2)),适用于较小规模的数据。
public int eraseOverlapIntervals(int[][] intervals) { int len = intervals.length; if (len == 0) return 0; // 按结束时间排序 Arrays.sort(intervals, new Comparator() { @Override public int compare(int[] interval1, int[] interval2) { return interval1[1] - interval2[1]; } }); int lastEnd = -1; int count = 0; for (int i = 0; i < len; i++) { if (intervals[i][0] > lastEnd) { count++; lastEnd = intervals[i][1]; } } return len - count;}
public int eraseOverlapIntervals(int[][] intervals) { int len = intervals.length; if (len == 0) return 0; // 按开始时间排序 Arrays.sort(intervals, new Comparator() { @Override public int compare(int[] interval1, int[] interval2) { return interval1[0] - interval2[0]; } }); // 初始化动态规划数组 int[] dp = new int[len]; Arrays.fill(dp, 1); // 预处理以便二分查找 List endTimes = new ArrayList<>(); for (int i = 0; i < len; i++) { endTimes.add(intervals[i][1]); } // 对于每个区间,找到最大的不重叠区间索引 for (int i = 0; i < len; i++) { int currentStart = intervals[i][0]; int maxEndIndex = i; for (int j = i - 1; j >= 0; j--) { if (endTimes[j] < currentStart) { maxEndIndex = j; break; } } if (maxEndIndex >= 0) { dp[i] = dp[maxEndIndex] + 1; } else { dp[i] = dp[i] + 1; } } int max = dp[len - 1]; return max;}
无论采用哪种方法,目标是最大化不相交的区间数量。动态规划方法通常更复杂,但对于理解问题有帮助。贪心方法在该情况下更为高效。
转载地址:http://twjzk.baihongyu.com/