贪心-合并区间、交集、无重叠区间、俄罗斯套娃信封
1. 给出一个区间的集合,请合并所有重叠的区间。
1 /* 2 * https://leetcode-cn.com/problems/merge-intervals/ 3 * 4 * 给出一个区间的集合,请合并所有重叠的区间。 5 * */ 6 import java.util.ArrayList; 7 import java.util.Arrays; 8 import java.util.Comparator; 9 import java.util.List; 10 11 public class code056_MergeIntervals 12 { 13 public int[][] merge(int[][] intervals) { 14 if (intervals == null || intervals.length == 0) 15 return intervals; 16 Arrays.sort(intervals, new Comparator<int[]>() 17 { 18 @Override 19 public int compare(int[] o1, int[] o2) 20 { 21 if (o1[0] == o2[0]) 22 return o1[1] - o2[1]; 23 return o1[0] - o2[0]; 24 } 25 }); 26 List<int[]> res = new ArrayList<>(); 27 res.add(intervals[0]); 28 for (int i = 0; i < intervals.length; i++) 29 { 30 int[] last = res.get(res.size() - 1); 31 int[] curr = intervals[i]; 32 if(curr[0] <= last[1]){ 33 last[1] = Math.max(last[1], curr[1]); 34 }else { 35 res.add(curr); 36 } 37 } 38 int[][] result = new int[res.size()][2]; 39 for (int i = 0; i < result.length; i++) 40 { 41 result[i] = res.get(i); 42 } 43 return result; 44 } 45 }
2. 给定两个由一些闭区间组成的列表,每个区间列表都是成对不相交的,并且已经排序。返回这两个区间列表的交集。
1 /* 2 * https://leetcode-cn.com/problems/interval-list-intersections/ 3 * 4 * 给定两个由一些闭区间组成的列表,每个区间列表都是成对不相交的,并且已经排序。 5 * 6 * 返回这两个区间列表的交集。*/ 7 import java.util.ArrayList; 8 import java.util.List; 9 10 public class code986_IntervalListIntersections 11 { 12 public int[][] intervalIntersection(int[][] A, int[][] B) { 13 if(A == null) 14 return A; 15 if(B == null) 16 return B; 17 List<int[]> res = new ArrayList<>(); 18 int l1 = A.length, l2 = B.length; 19 int i = 0, j = 0; 20 while(i < l1 && j < l2){ 21 int a1 = A[i][0], a2 = A[i][1]; 22 int b1 = B[j][0], b2 = B[j][1]; 23 if(a1 <= b2 && a2 >= b1){ 24 res.add(new int[]{Math.max(a1, b1), Math.min(a2, b2)}); 25 } 26 if(a2 < b2){ 27 i++; 28 }else{ 29 j++; 30 } 31 } 32 int[][] result = new int[res.size()][2]; 33 for(int k = 0; k < result.length; k++){ 34 result[k] = res.get(k); 35 } 36 return result; 37 } 38 }
3. 给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
1 import java.util.Arrays; 2 import java.util.Comparator; 3 4 /* 5 * https://leetcode-cn.com/problems/non-overlapping-intervals/ 6 * 给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。 7 * */ 8 class Solution 9 { 10 public int eraseOverlapIntervals(int[][] intervals) 11 { 12 if (intervals.length == 0) 13 return 0; 14 Arrays.sort(intervals, new Comparator<int[]>() 15 { 16 public int compare(int[] a, int[] b) 17 { 18 return a[1] - b[1]; 19 } 20 }); 21 int count = 1; 22 int init_end = intervals[0][1]; 23 for (int[] inter : intervals) 24 { 25 int start = inter[0]; 26 if (start >= init_end) 27 { 28 count++; 29 init_end = inter[1]; 30 } 31 } 32 return intervals.length - count; 33 } 34 }
4. 请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)
1 /* 2 * 3 * https://leetcode-cn.com/problems/russian-doll-envelopes/ 4 * 5 * 给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。 6 * 当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。 7 * 请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。 8 **/ 9 import java.util.Arrays; 10 import java.util.Comparator; 11 12 public class code354_RussianDollEnvelopes 13 { 14 public int maxEnvelopes(int[][] envelopes) { 15 Arrays.sort(envelopes, new Comparator<int[]>() 16 { 17 @Override 18 public int compare(int[] o1, int[] o2) 19 { 20 if (o1[0] == o2[0]) 21 return o2[1] - o1[1]; 22 return o1[0] - o2[0]; 23 } 24 }); 25 int[] height = new int[envelopes.length]; 26 for (int i = 0; i < envelopes.length; i++){ 27 height[i] = envelopes[i][1]; 28 } 29 return LenLongestIncreaseSubSequence(height); 30 } 31 32 private int LenLongestIncreaseSubSequence(int[] nums) 33 { 34 int maxLength = 0; 35 int dp[] = new int[nums.length]; 36 for (int i = 0; i < nums.length; i++) 37 { 38 dp[i] = 1; 39 } 40 for (int i = 0; i < dp.length; i++) 41 { 42 for (int k = 0; k < i; k++) 43 { 44 if (nums[i] > nums[k]) 45 // dp[i]:以i结尾,最长的递增子序列 46 dp[i] = Math.max(dp[i], dp[k] + 1); 47 } 48 maxLength = Math.max(maxLength, dp[i]); 49 } 50 return maxLength; 51 } 52 53 }