俄羅斯套娃信封問題 轉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)。

相關文章
相關標籤/搜索