354RussianDollEnvelopes

题意:给定一系列的标有(w, h)的信封,当且仅当一个信封的长和宽都小于另一个信封时,才能装进去。最多能嵌套多少个信封?

思路:以w为主序,h为次序将信封排序,当前信封标记为(w, h),找到宽度大于w的信封中且首个高度大于h的信封。数据结构二维数组,一维表示信封数,二维表示(w,h)。

参考leetcode discuss,注意h为降序,否则会导致相同宽度的信封加入计数。f(n组数) = f(n-1组数) + 1, 将w相同的信封视为同一组,第n组的最大h大于第(n-1)的h,信封数才能加1,而且能保证统计的信封中w都不同。

    public int maxEnvelopes(int[][] envelopes) {
        if(envelopes.length == 0 || envelopes == null){
        	return 0;
        }
        Arrays.sort(envelopes, new Comparator
   
    () {
        	//信封排序:w为主序,h为次序
			public int compare(int[] o1, int[] o2) {
				if(o1[0] == o2[0]){
					return o2[1] - o1[1];//注意:降序
				} else{
					return o1[0] - o2[0]; //w升序
				}
			}
		});
        int dp[] = new int[envelopes.length]; //默认初始化全部为0
        int len = 0;
        for(int[] envelop : envelopes){ //w非递减顺序,只需考虑h
        	int index = Arrays.binarySearch(dp, 0, len, envelop[1]);
        	if(index < 0){
        		index = -(index + 1); //返回值(-(insertionPoint) - 1)
        	}
        	dp[index] = envelop[1]; //更新变小(前面的h越小,信封数越多的可能性越大)
        	if(index == len){
        		len++;
        	}
        }
        return len;
    }
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值