LeetCode:计算最多容纳多少个“俄罗斯套娃“信封.

You have a number of envelops with widths and heights given as a pair of integers(m,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])

题目大意:
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式(w,h)出现.当另一个信封的宽度和高度都比这个信封大的时候,
这个信封可以放到另外一个信封里面,如同俄罗斯套娃一样.请计算最多有多少个信封能组成一组"俄罗斯套娃"信封.

解题思路:
排序+二分查找
这道题与第300题有点类似.能组成俄罗斯套娃的条件就是能找到一个最长上升序列.但是这道题是二维的,要求能找到在二维
上都能满足条件的最长上升子序列.先降维,把宽度进行升序排序,然后在高度上寻找最长上升子序列.高度序列的最长严格递
增子序列的长度就是装的最多的信封的个数.

Go语言实现

package main

import (
	"fmt"
	"sort"
)

/*自定义排序sort.Sort需要Len(),Less(),Swap()*/
/*
type sortEnvelops [][]int

func (s sortEnvelops) Len() int{
	return len(s)
}
func (s sortEnvelops) Less(i,j int) bool{
	if s[i][0]==s[j][0]{
		return s[i][1]>s[j][1]
	}
	return s[i][0]<s[j][0]
}
func (s sortEnvelops) Swap(i,j int){
	s[i],s[j]=s[i],s[j]
}
*/
func maxEnvelops(envelops [][]int)int{
	/*左边升序,右边降序排序*/
	sort.Slice(envelops, func(i, j int) bool {
		if envelops[i][0]==envelops[j][0]{
			return envelops[i][1]>envelops[j][1]
		}
		return envelops[i][0]<envelops[j][0]
	})
	/*sort.Sort(sortEnvelops(envelops)排序*/
	ans,count:=make([]int,len(envelops)),0
	/*可以省略count、ans,dp:=[]int{}*/
	for _,num:=range envelops{
		low,high:=0,count /*high=len(dp)*/
		for low<high{
			mid:=low+(high-low)>>1
			if num[1]>ans[mid]{/*换成dp[mid]*/
				low=mid+1
			}else {
				high=mid
			}
		}
		/*以下的部分替换成
		if low==len(dp){
		    dp=append(dp,num[1])
		}else{
		    dp[low]=num[1]
		}
		*/
		if low==count{
			count++
		}
		ans[low]=num[1]
	}
	return count
}
func main(){
	envelops:=[][]int{{5,4},{6,4},{6,5},{2,5},{7,6}}
	fmt.Println(maxEnvelops(envelops))
}

Java语言实现

import java.util.Arrays;

public class RussianDollEnvelopes {
    public int maxEnvelopes(int[][] envelopes){
        Arrays.sort(envelopes,(int[] a,int[] b)->{
            if(a[0]==b[0]){
                return b[1]-a[1];
            }
            return a[0]-b[0];
        });
        int[] heights=new int[envelopes.length];
        for(int i=0;i<envelopes.length;++i){
            heights[i]=envelopes[i][1];
        }
        return back(heights);
    }
    private int back(int[] nums){
        int len=0;
        for(int num:nums){
            int i=Arrays.binarySearch(nums,0,len,num);
            if(i<0){
                i=-(i+1);
            }
            if(i==len){
                len++;
            }
            nums[i]=num;
        }
        return len;
    }
    public static void main(String[] args){
        int[][] envelopes={{5,4},{6,4},{6,7},{2,3}};
        RussianDollEnvelopes so=new RussianDollEnvelopes();
        System.out.println(so.maxEnvelopes(envelopes));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值