我正在参加「掘金·启航计划」点击查看活动详情的第一天
今天我们来回顾一下leetcode第213场周赛的题目🤔🤔🤔。
题目链接在这里213场周赛
题目3
题意
打开这个题目映入眼帘的是一幅动图,乍一看还挺可爱😜😜😜
题意比较简单,也容易懂。 给了我们一个数组,每个数字代表一个建筑的高度。我们其实位于第0个建筑位置上,然后向右移动,如果低的建筑可以直接跳过去,遇到高的建筑可以通过垫砖块或者 撑梯子过去。
题目想让我们用最优的方法来算出来最远可以到达哪个建筑。
思路
读懂题目之后,可能一开始会想优先用砖块,等砖块不够用了,再用梯子,但是这种方式在一些测试用例会通过不了。
比如
[1,5,1,2,3,4,10000] 4 1
这个例子中我们有4块砖,1个梯子 第二个建筑比第一个高4,第4个建筑比第3个高1,第5个建筑比第4个高1,第6个建筑比第5个高1
如果先用砖块的话,我们最多只能到第4个建筑
如果我们先用梯子的话,可以到达第6个建筑
为什么会出现这种差异呢?
观察数据我们可以发现,这个例子中第2个建筑和第1个建筑的差值比后面的要大很多,这时用梯子就比较物尽其用。
其实这也是我们想要做的,把梯子使用在高度差最大的地方。但是我们在向右移动的过程中,不知道将来会遇到那些高度差。
所以,我们可以把这些高度差记录在一个数据结构中,在我们向后移动时,如果砖块用完了,为了防止后面还会有高度低的情况而且我们之前在使用梯子的时候没有用,我们把之前经过的高度的最大值从那个数据结构中拿出来,然后把砖块收回来,替换成梯子,不断重复这个过程,每次在使用梯子时,都替换成之前用砖块最多的高度上面,直到砖块和梯子都没有了,我们这个过程的操作也就是最优的了。
这样分析之后,我们需要找到那个可以在集合中快速取出最大值的结构,我们很快就会找到 最大堆
然后,根据以上的分析过过程,我们就可以实现这个逻辑。
代码实现
题目4
题意
终于来到了周赛的第四题,一如以往的是一道被打上困难标签的题目
如果你做过很多深搜广搜类的题目,那么这题目你一读就懂。
题目说给了一个二维区域,Bob从0,0点出发到达m,n点。
经过的路径使用字符串表示,每向下走一步标记为V,向右走一步标记为H,这样就会形成很多路径。
题目让我们求这些路径字符串按照字典序排序的第k个字符串
思路
这道题相信你还没有读完题就准备用深搜或者广搜了,但是当你真正尝试之后,会发现结果是超时。
原因就在于,需要遍历mn区域的所有路径,时间复杂度巨高。
那么除了传统的搜索,这里还有没有别的方法呢?
其实,当你注意到题目数据范围中k的范围时,可能就会往组合数学这方面想了。
那么,从字符组合的角度如何考虑呢?
- 因为题目规定Bob只能向右或者向下走,又因为区域高m+1宽n+1,这也就意味着他无论怎样走,肯定会向下走m步,向右走n步
- 进而,说明路径字符串只会有HV组成,因为每次走哪一步都有可能,所以所有的结果其实就是m个V和n和H的组合数
- 知道这些有什么用呢?不要着急,我们在来回顾一下组合数方面的知识.
- 如果是m个V和n个H进行组合,会形成多少中结果呢? 根据高中数学的知识,我们知道是 (m+n)!/m!n!,相当于是在装了5种球的口袋中摸2个球,不区分顺序,会产生多少种结果呢? 当然是 5*4/2*1了
- 在这里也一样,我们可以知道以H开头的字符的组合数应该有 C(m+n-1)(m)
- 如果k小于H开头的字符数,那就可以确定第k个组合的第一个字符是H
- 然后在所有H开头的字符组合中,找到第k个字符,所有以H开头的字符组合数,相当于 m个V和n-1个H的组合数
- 如果k大于H开头的字符组合数,那么第k个组合第一个字符一定是V
- 记comb=C(m+n-1)(m),然后在所有V开头的字符组合中,找到第k-comb个字符,所有以V开头的字符组合数,相当于 m-1个V和n个H的组合数
- 这样找下去直到mn都为0,当然因为我们是和H开头的字符组合数比较,所以当m为0时,剩下的都是H了,这时只需要将剩下的都记为H即可
代码实现
结束语
如果有更好的分析思路,欢迎大家在评论区发表看法!⛄