zoukankan      html  css  js  c++  java
  • [LeetCode] 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]).

    信封的嵌套问题,就像俄罗斯套娃一样,一个套一个,求能套的最多数量。

    300. Longest Increasing Subsequence类似,从那题一维变成了两维。

    先给信封排序,按信封的宽度从小到大排,宽度相等时,高度大的在前面。问题就简化了成了找高度数字中的Longest Increasing Subsequence。

    Java: Naive

    public int maxEnvelopes(int[][] envelopes) {
        if(envelopes==null||envelopes.length==0)
            return 0;
     
        Arrays.sort(envelopes, new Comparator<int[]>(){
            public int compare(int[] a, int[] b){
                if(a[0]!=b[0]){
                    return a[0]-b[0];
                }else{
                    return a[1]-b[1];
                }
            }
        });
        int max=1;
        int[] arr = new int[envelopes.length];
        for(int i=0; i<envelopes.length; i++){
            arr[i]=1;
            for(int j=i-1; j>=0; j--){
                if(envelopes[i][0]>envelopes[j][0]&&envelopes[i][1]>envelopes[j][1]){
                    arr[i]=Math.max(arr[i], arr[j]+1);
                }
            }
            max = Math.max(max, arr[i]);
        }
     
        return max;
    } 

    Java: Binary Search

    public int maxEnvelopes(int[][] envelopes) {
        if(envelopes==null||envelopes.length==0)
            return 0;
     
        Arrays.sort(envelopes, new Comparator<int[]>(){
            public int compare(int[] a, int[] b){
                if(a[0]!=b[0]){
                    return a[0]-b[0]; //ascending order
                }else{
                    return b[1]-a[1]; // descending order
                }
            }
        });
     
        ArrayList<Integer> list = new ArrayList<Integer>();
     
        for(int i=0; i<envelopes.length; i++){
     
            if(list.size()==0 || list.get(list.size()-1)<envelopes[i][1])
                list.add(envelopes[i][1]);
     
            int l=0;
            int r=list.size()-1;
     
            while(l<r){
                int m=l+(r-l)/2;
                if(list.get(m)<envelopes[i][1]){
                    l=m+1;
                }else{
                    r=m;
                }
            }
     
            list.set(r, envelopes[i][1]);
        }
     
        return list.size();
    }

    Python:

    class Solution(object):
        def maxEnvelopes(self, envelopes):
    
            def insert(target):
                left, right = 0, len(result) - 1
                while left <= right:
                    mid = left + (right - left) / 2
                    if result[mid] >= target:
                        right = mid - 1
                    else:
                        left = mid + 1
                if left == len(result):
                    result.append(target)
                else:
                    result[left] = target
    
            result = []
            envelopes.sort(lambda x, y: y[1] - x[1] if x[0] == y[0] else 
                                        x[0] - y[0])
            for envelope in envelopes:
                insert(envelope[1])
    
            return len(result)
    

    C++:

    class Solution {
    public:
        int maxEnvelopes(vector<pair<int, int>>& envelopes) {
            vector<int> dp;
            sort(envelopes.begin(), envelopes.end(), [](const pair<int, int> &a, const pair<int, int> &b){
                if (a.first == b.first) return a.second > b.second;
                return a.first < b.first;
            });
            for (int i = 0; i < envelopes.size(); ++i) {
                int left = 0, right = dp.size(), t= envelopes[i].second;
                while (left < right) {
                    int mid = left + (right - left) / 2;
                    if (dp[mid] < t) left = mid + 1;
                    else right = mid;
                }
                if (right >= dp.size()) dp.push_back(t);
                else dp[right] = t;
            }
            return dp.size();
        }
    };
    

    类似题目:

    [LeetCode] 300. Longest Increasing Subsequence 最长递增子序列

    All LeetCode Questions List 题目汇总

      

  • 相关阅读:
    类和对象系列教材 (十二)- 怎么写一个Java的饿汉式与懒汉式单例模式
    类和对象系列教材 (十二)- 怎么写一个Java的饿汉式与懒汉式单例模式
    [LeetCode] 285. Inorder Successor in BST
    [LeetCode] 671. Second Minimum Node In a Binary Tree
    [LeetCode] 230. Kth Smallest Element in a BST
    [LeetCode] 238. Product of Array Except Self
    [LeetCode] 273. Integer to English Words
    [LeetCode] 266. Palindrome Permutation
    [LeetCode] 409. Longest Palindrome
    [LeetCode] 124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8532330.html
Copyright © 2011-2022 走看看