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)

Example:
Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll is 3([2,3] => [5,4] => [6,7]).

題意:

給定數個信封,一個大的信封可以裝比它小的信封,那一個信封最多可以裝進幾個信封?(若較小的信封長或寬與較大的信封一樣則無法裝入)

例如:[[5,4],[6,4],[6,7],[2,3]],最多可以裝進3個信封:3([2,3] => [5,4] => [6,7])。

題解:

這題與最大遞增子序列很相似,只不過改成了2維,但也增加了難度,但萬變不如其中,我們一樣利用最大遞增子序列的思想來解這一道題。

  1. 一個全局最大信封數量
  2. 將這個數組進行倒序排序
  3. 新增一個數組紀錄每一個信封的最大裝進信封量,至少為1(代表自己)
  4. 歷遍每個信封
    1. 掃描所有比自己小(體積)的信封
    2. 比較該信封裝進信的數量,若為最大則裝進這個信封
    3. 掃描完比自己體積小的信封後,維護全局最大信封數
  5. 輸出最大信封數
這一題的dp數組類似於下面:
信封大小        [5,4] [4,3] [4,2] [3, 1] [3, 1]
=======================================
信封數量        3      2      2      1      1

package LeetCode.Hard;

import java.util.Arrays;
import java.util.Comparator;

public class RussianDollEnvelopes {
    
    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];
                }
            }
        });
        
        //存儲每個信封的最大容納信封的數量
        /*
        ex:
        [5,4] [4,3] [4,2] [3, 1] [3, 1]
        =======================================
        3     2     2     1      1
        */
        int[] dp = new int[envelopes.length];
        //紀錄最大數量
        int max = 1;
        for(int i = 0; i < envelopes.length; i ++) {
            dp[i] = 1;
            //往下找尋比較小的信封,若符合條件,則計入數量當中
            for(int j = i - 1; j >= 0; j --) {
                if(envelopes[i][0] > envelopes[j][0] && envelopes[i][1] > envelopes[j][1]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            //維護最大數量
            max = Math.max(dp[i], max);
        }
        
        
        return max;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值