俄罗斯套娃信封问题【python实现】

问题描述

俄罗斯套娃信封问题

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。
当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
注意:不允许旋转信封。

示例 1:
输入:envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出:3
解释:最多信封的个数为
3, 组合为:
[2,3] => [5,4] => [6,7]。

示例 2:
输入:envelopes = [[1,1],[1,1],[1,1]]
输出:1

实现方式

先用信封宽度从小到大排序,再在信封宽度的排序前提下,排序信封高度。

sorted()好像能方便很多,但是我写到一半才发现这个函数可以简单解决😢

😠😠😠脾气上来了,咱也不管那么多了,就按老路子整了,就当也练习下sorted()底层代码了。😠😠

大家别学我,可以尝试着用sorted()解决下问题。🏀

import copy

def russianNestEnvelope(envelopes):
    envelopes = envelopes
    width = []
    lopew = []
    lopew_index = []
    height = []
    lopeh = []
    Nest = []
    for id, lope in enumerate(envelopes):
        width.append(lope[0])
        height.append(lope[1])
       print(f"原始宽度:{width}")
    print(f"原始高度:{height}")
    width_copy = copy.deepcopy(width)
    while len(width) >= 1:  #
        minw = min(width)  # 因为是从小到大排序,所以找最小值
        lopew.append(minw)  # 找到后直接放入新容器
        idb = [i for i, x in enumerate(width_copy) if x == minw]  # 找最小值的索引
        if len(idb) == 1:  # 如果此最值无重复,那么idb只返回一个值,但是是以list形式
            lopew_index.append(idb[0])  # 将index放入新容器
        else:  # 若idb返回值不是一个,说明此最小值有重复值
            hinsamew=[]
            for idh in idb: # 重复值中,w相同情况下,按h小在前面进行索引排序
                hinsamew.append(height[idh])
            idbh=[u for u, v in enumerate(hinsamew) if v == min(hinsamew)] 
            lopew_index.append(idb[idbh[0]])  # 将索引放入容器
            width_copy[idb[idbh[0]]] = 0  # 将重复值中的第一个值赋0(如果要排序的列表中没有0,有0,就随便赋值一个排序列表中没有的数据)
        width.remove(minw)  # 将排序列表中的最小值删除,以便下次寻找新的最小值
    for idh in lopew_index: # 宽度排序前提下的,高度排序。
        lopeh.append(height[idh])
        
        
    # 有上面lopew和lopeh两个list后就可以保证,从头到尾找一次就能找到包含信封最多的套娃组合。
    i = 0 # 初始索引
    step = 1 # 初试跳步步长
    Nest.append([lopew[0], lopeh[0]]) # 初试套娃信封(最内层的套娃)
    while i + step <= len(envelopes) - 1:
        currentw = lopew[i] # 当前信封宽
        currenth = lopeh[i] # 当前信封高
        nextw = lopew[i + step] # 下一个信封宽
        nexth = lopeh[i + step] # 下一个信封高
        if currentw != nextw and currenth < nexth: # 套娃规则,外层宽高严格大于内层宽高
            Nest.append([nextw, nexth])
            i = i + step
        else:
            step += 1
    print(f"原始信封序列:{envelopes}")
    print(f"排列后的信封序列:{newenvelopes}")
    print(f"最大套娃组合个数:{len(Nest)}")
    print(f"组合为:{Nest}")
    return Nest


russianNestEnvelope([[3, 7], [5, 8], [5, 4], [7, 5], [5, 5], [6, 1], [4, 3], [8, 3], [7, 6], [3, 4]])

result:

原始宽度:[3, 5, 5, 7, 5, 6, 4, 8, 7, 3]
原始高度:[7, 8, 4, 5, 5, 1, 3, 3, 6, 4]
原始信封序列:[[3, 7], [5, 8], [5, 4], [7, 5], [5, 5], [6, 1], [4, 3], [8, 3], [7, 6], [3, 4]]
排列后的信封序列:[[3, 4], [3, 7], [4, 3], [5, 4], [5, 5], [5, 8], [6, 1], [7, 5], [7, 6], [8, 3]]
最大套娃组合个数:3
组合为:[[3, 4], [5, 5], [7, 6]]

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值