Go 力扣题解《354.俄罗斯套娃信封问题》(下)笔记 06 | 青训营

132 阅读2分钟

本篇笔记是笔者在第六届字节跳动青训营期间使用 Go 语言解决了力扣《354.俄罗斯套娃信封问题》【困难】后,对官方题解解法二的理解

在上一节中,我们成功地解决了排序的问题,得到了一个可供我们解题的信封序列。接下来我们遍历该序列,实质上是求解该问题的每个子问题的解,在这个过程中,我们可以观察到一个很有意思的特点:

若信封可能的套法 A 能够套 n 次,套法 A 中最后一层也就是最大的信封大小为 BigA;信封可能的套法 B 能套 n + 1 次,套法 B 中最后一层也就是最大的信封大小为 BigB,此时 BigB 在整个序列中一定位于 BigA 的后面。因为由排序可知:若 BigB 可以套下 BigA,则 BigB 在整个序列中考虑宽和高,其一定位于 BigA 的后面。因此我们可以使用数组(切片),以当前序列 长度为索引,保存信封的高。这里为什么是高呢,因为由于我们的排序操作,按顺序遍历信封序列的情况下,高已经变成了唯一能够表示信封大小的属性。最后,不断进行状态转移,直至遍历完成即可。遍历的各种情况如下:

· 建立一个数组(切片)f,其中 f[i] 表示长度为i(套了i层信封)后的最小信封的高度,然后开始顺序遍历我们上面排好序的信封大小序列,获取信封A高度h用来确保信封正确地套在比它小的信封上,会有下面几种情况:

  • 在 f 数组中,查找是否存在比h严格大(>)的信封B

    • 若没有

      • 存在和该信封高度相等的信封C,序号为idxC:

        由于高度相等,因此更新以该信封C为最大信封的状态f[idxC]为h,其效果与不更新相同

      • 不存在和该信封高度相等的信封:

        由于该信封的宽度已经是最大了(排序保证),因此其可以套在当前套了最多次信封的那个信封上,即 len(f) + 1,且在此长度位置中记录A的高度

    • 若有,则该信封A不可以与比它高度还大的信封B嵌套,因为A的宽度一定小于或等于信封B[排序保证]。此时查找具有严格小于h的最大高度的信封C,其序号为idxC,更新f[idxC]为h即可

最后,数组(切片) f 的长度,即为所求的答案