354. Russian Doll Envelopes
You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envelope can fit into another if and only if both the width and height of one envelope is greater than the width and height of the other envelope. What is the maximum number of envelopes can you Russian doll? (put one inside other) Note: Rotation is not allowed. Example: Input: [[5,4],[6,4],[6,7],[2,3]] Output: 3 Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]). https://leetcode.com/problems/russian-doll-envelopes/discuss/82763/Java-NLogN-Solution-with-Explanation 1. Sort the array. Ascend on width and descend on height if width are same. 2. Find the longest increasing subsequence based on height. * Since the width is increasing, we only need to consider height. * [3, 4] cannot contains [3, 3], so we need to put [3, 4] before [3, 3] when sorting otherwise it will be counted as an increasing number if the order is [3, 3], [3, 4] why sort height in descending order? prevent calculating the envelope with the same width? For example [3, 1] [3, 2] [3, 3] will get 3, but [3, 3], [3, 2], [3, 1] will get 1.
lamda expression and n^2 longest increasing subsequence
int[] = width, height
Arrays.sort(envelops, (e1, e2) -> e1[0] == e2[0] ? e2[1] - e1[1] : e1[0] - e2[0]);
e2[1] - e1[1] is decreasing order on height
e1[0] - e2[0] is increasing order on width
class Solution { public int maxEnvelopes(int[][] envelops) { // so the envelop: width, height // sort the envelop with width in asending order, if there are envelop with the same width // arrange them with height in descending order, and then try to find the longest increasing subsequence // in this , by height // sanity check if(envelops == null || envelops.length == 0 || envelops[0] == null || envelops[0].length != 2) return 0; // sort the envelops by the width in increasing order , if two width is the same, sort by height decreaisng order Arrays.sort(envelops, (e1, e2) -> e1[0] == e2[0] ? e2[1] - e1[1] : e1[0] - e2[0]); // Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName)); int[] array = new int[envelops.length]; for(int i = 0; i < envelops.length; i++){ array[i] = envelops[i][1]; } return lis(array); } private int lis(int[] nums) { if(nums == null || nums.length == 0) return 0; int res = 1; int n = nums.length; int[] dp = new int[n]; dp[0] = 1; for(int i = 1; i < n; i++){ int prev = 0; for(int j = 0; j < i; j++){ if(nums[j] < nums[i]){ prev = Math.max(prev, dp[j]); } } dp[i] = prev + 1; res = Math.max(res, dp[i]); } return res; } }
lamda expression and binary search in longest increasing subsequence
class Solution { public int maxEnvelopes(int[][] envelops) { // so the envelop: width, height // sort the envelop with width in asending order, if there are envelop with the same width // arrange them with height in descending order, and then try to find the longest increasing subsequence // in this , by height // sanity check if(envelops == null || envelops.length == 0 || envelops[0] == null || envelops[0].length != 2) return 0; // sort the envelops by the width in increasing order , if two width is the same, sort by height decreaisng order Arrays.sort(envelops, (e1, e2) -> e1[0] == e2[0] ? e2[1] - e1[1] : e1[0] - e2[0]); // Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName)); int[] array = new int[envelops.length]; for(int i = 0; i < envelops.length; i++){ array[i] = envelops[i][1]; } return lis(array); } private int lis(int[] nums) { if(nums == null || nums.length == 0) return 0; List<Integer> res = new ArrayList<>(); res.add(nums[0]); for(int i = 1; i < nums.length; i++){ int cur = nums[i]; if(cur == res.get(res.size() - 1)) continue; if(cur > res.get(res.size() - 1)){ res.add(cur); }else{ int index = bs(res, cur); // replacement res.set(index, cur); } } return res.size(); } private int bs(List<Integer> res, int newNum){ // find the index of the element in the list, which is the first number that is bigger than the new element int left = 0; int right = res.size() - 1; while(left < right){ int mid = left + (right - left) / 2; if(res.get(mid) == newNum){ return mid; }else if(res.get(mid) > newNum){ right = mid; }else{ // res.get(mid) < newNum left = mid + 1; } } return left; } }
posted on 2018-11-08 01:40 猪猪🐷 阅读(119) 评论(0) 收藏 举报
                    
                
                
            
        
浙公网安备 33010602011771号