美文网首页
IOS 算法(困难篇) ----- 俄罗斯套娃信封问题

IOS 算法(困难篇) ----- 俄罗斯套娃信封问题

作者: ShawnAlex | 来源:发表于2021-03-04 19:31 被阅读0次

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

例子

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

输入:envelopes = [[1,1],[1,1],[1,1]]
输出:1

解题思路

题意好理解, 不过这道题一共2个难点需要重点处理下

1.排序
2.排序之后的查找

首先 第一维度(下标为0元素组成的数组)正序排列便于处理, 这个是大家肯定会想到的处理方式,
那么我们重点看下第二维度(下标为1元素组成的数组)怎么处理

例子:

[[2, 3], [4, 5], [6, 6], [6, 7]]

第一维度 [2, 4, 6, 6] (下标为0元素组成的数组)
第二维度 [3, 5, 6, 7] (下标为1元素组成的数组)

结果3, 没问题, 看第一维度就可以得出,

但是先不看第一维度, 我们看第二维度呢 [3, 5, 6, 7] 应该是4啊

那么我们再看下这个

[[2, 3], [4, 5], [6, 7], [6, 6]]

第二维度 [2, 4, 6, 6]
第二维度 [3, 5, 7, 6]

这样看第二维度 [3, 4, 7, 6], 最长递增子序列的长度是 3 即正确结果

所以,利用这个特性 第一个维度递增,如果第一维度相等,第二个维度递减的顺序 进行排序处理,
然后找第二维度最长递增子序列即可

这里我建议先做下IOS 算法(中级篇) ----- 最长递增子序列 , 后面找最大就比较好理解了

未翻译版
    func maxEnvelopes(_ envelopes: [[Int]]) -> Int {

        if envelopes.count == 0 { return 0 }
        
        var temp = envelopes
        temp = temp.sorted { (a, b) -> Bool in
            if a[0] == b[0]{
                return a[1] > b[1]
            } 
            return a[0] < b[0]
        }
        
        var f = Array.init(repeating: 1, count: temp.count)
        for i in 0..<temp.count  {
            for j in 0..<i {
                if(temp[i][1] > temp[j][1]) {
                    f[i] = max(f[i], f[j]+1)
                }
            }
        }
        return f.max() ?? 1
}
翻译版
    func maxEnvelopes(_ envelopes: [[Int]]) -> Int {

        // 空数组直接返回
        if envelopes.count == 0 { return 0 }
        
        // 定义一个容器数组为原数组
        var temp = envelopes

        // 容器数组按上述方法排序
        temp = temp.sorted { (a, b) -> Bool in
            
            // 第一维度相等, 则第二维度倒序排列
            if a[0] == b[0]{
                return a[1] > b[1]
            } 
            // 第一维度正序排列
            return a[0] < b[0]
        }

        // 接下来就变成了找第二维度最长递增子序列
        var f = Array.init(repeating: 1, count: temp.count)

        // 动态规划求解找到最长子序列
        for i in 0..<temp.count  {
            for j in 0..<i {
                if(temp[i][1] > temp[j][1]) {
                    f[i] = max(f[i], f[j]+1)
                }
            }
        }
        // 返回结果
        return f.max() ?? 1
}

题目来源:力扣(LeetCode) 感谢力扣爸爸 :)
IOS 算法合集地址

相关文章

网友评论

      本文标题:IOS 算法(困难篇) ----- 俄罗斯套娃信封问题

      本文链接:https://www.haomeiwen.com/subject/phnkqltx.html