俄罗斯套娃信封问题 转https://www.jianshu.com/p/9d9495ef4372

给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另外一个信封的宽度和高度都比这个信封大的时候,这个信封就能够放进另外一个信封里,如同俄罗斯套娃同样。数组

请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(便可以把一个信封放到另外一个信封里面)。bash

说明:ide

不容许旋转信封。ui

示例:spa

输入: envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出: 3 
解释: 最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。
复制代码
class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        if( envelopes.length == 0 || envelopes[0].length == 0 ){
            return 0;
        }
        Arrays.sort( envelopes , new Comparator<int[]>(){
            @Override
            public int compare( int[] o1 , int[] o2 ){
                if( o1[ 0 ] == o2[ 0 ] ){
                    return o1[ 1 ] - o2[ 1 ];
                }
                return o1[ 0 ] - o2[ 0 ];
            }
        } );
        int max = 0;
        int[] dp = new int[ envelopes.length ];
        for( int i = 0 ; i < envelopes.length ; i++ ){
            dp[ i ] = 1;
            for( int j = 0 ; j < i ; j++ ){
                if( envelopes[ i ][ 0 ] > envelopes[ j ][ 0 ] && envelopes[ i ][ 1 ] > envelopes[ j ][ 1 ]  ){
                    dp[ i ] =  Math.max( dp[ j ] + 1 , dp[ i ] );
                }
            }
            max = Math.max( max ,  dp[ i ] );
        }
        return max;
    }
}
复制代码

针对状况Icode

当每一个信封的宽度和高度不同时,咱们能够对信封按照宽度从小到大进行排序,好比针对信封[[3,2],[2, 4],[4,3],[5, 6],[6,5]排序后变为排序

w: 2 -> 3 -> 4 -> 5 -> 6leetcode

h: 4 -> 2 -> 3 -> 6 -> 5io

此时,由于信封的宽度w已是从小到大排列了,要想信封能够套,这要求关于信封高度h的数组[4, 2, 3, 6, 5]是的子序列是递增的,且要求是最长的(题目要求的是最多的信封),因此能够转化为另外一个问题:给定数组,求它的最长递增子序列(也称最长上升子序列)。关于这个问题在leetcode300有具体描述。class

最长递增子序列

好比给的数组arr = [3, 1, 2, 5, 4, 6]。

获得的最长递增子序列长度为4,即[1, 2, 5, 6]或[1, 2, 4, 6]。

这个问题的解法是动态规划,给一个相同长度的数组dp,dp[i]表示以arr[i]结尾的最长递增子序列,初始化都为1(自己构成最长递增子序列),即dp[i] = 1, 这个的动态转移方程(递推式)为,j从0到i - 1,若是arr[i] > arr[j], 这dp[i] = max(dp[i], dp[j] + 1)。

相关文章
相关标签/搜索