信封嵌套问题

题目:给定一个N行2列的二维数组,每一个小数组的两个值分别代表一个信封的长和宽。如果信封A 的长度都小于信封B,那么信封A可以放在信封B里,请返回信封最多嵌套多少层

举例:

matrix = [[3,4],[2,3],[4,5],[1,3],[2,2],[3,6],[1,2],[3,2],[2,4]]

信封最多可以套4层,从里到外分别是[1,2],[2,3],[3,4],[4,5],所以返回4

时间复杂度为O(NlogN)

 思路:数组长度从小到达排序,长度相等的信封宽度按照从大到小排序

长度排序之后,可以忽略长度,只看宽度数组,问题转化为宽度数组的最长递增子序列问题

# encoding = 'utf-8'

import numpy as np

matrix = [[3,4],[2,3],[4,5],[1,3],[2,2],[3,6],[1,2],[3,2],[2,4]]
matrix.sort(key=lambda x: (x[0],-x[1])) 

arr = []
for i in range(len(matrix)):
    arr.append(matrix[i][1])
 
def getOrderLIS(arr,dp):
 
    maxlen = 0
    index = 0
 
    """找到最大值及索引"""
    
    for i in range(len(arr)):
        if arr[i] > maxlen:
            maxlen = arr[i]
            index = i
 
    res = [0 for i in range(maxlen)]
    res[maxlen-1]= arr[index]
    maxlen -=1
 
    """找到之后,从右向左查找"""
    for j in range(index,-1):
        if arr[j] < arr[index] and dp[j] == dp[index] - 1:
            res[maxlen-1] = arr[j]
            maxlen -=1
            index = j
 
    return res

def getdp2(arr):
    
    dp = [0 for i in range(len(arr))]
    ends = [0 for i in range(len(arr))]
    
    right = 0
    dp[0] = 1
    ends[0] = arr[0]
    
    for i in range(1,len(arr)):
        l = 0
        r = right
        while l <= r:
            m = (l+r)//2
            if arr[i] > ends[m]:
                l = m + 1
            else:
                r = m - 1
                
        right = max(right,l)
        dp[i] = l + 1
        ends[l] = arr[i]
        
    return dp
 
def getlist(arr):
 
    if arr == None or len(arr) == 0:
        return None
 
    dp = getdp2(arr)
 
    return getOrderLIS(arr,dp)

getlist(arr)

最长递增子序列问题可参考:

https://blog.csdn.net/weixin_41362649/article/details/98470219

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值