0790. 多米诺和托米诺平铺
题目地址(790. 多米诺和托米诺平铺)
https://leetcode-cn.com/problems/domino-and-tromino-tiling/
题目描述
前置知识
动态规划
公司
暂无
思路
这种题目和铺瓷砖一样,这种题目基本都是动态规划可解。做这种题目的诀窍就是将所有的可能都列举出来,然后分析问题的最优子结构。最后根据子问题之间的递推关系解决问题。
如果题目只有 XX 型,或者只有 L 型,实际上就很简单了。而这道题是 XX 和 L,则稍微有点难度。力扣还有一些其他更复杂度的铺瓷砖,都是给你若干瓷砖,让你刚好铺满一个形状。大家做完这道题之后可以去尝试一下其他题相关目。
以这道题来说,所有可能的情况无非就是以下 6 种:
而题目要求的是刚好铺满 2 * N 的情况的总的可能数。
如上图 1,2,3,5 可能是刚好铺满 2 _ N 的瓷砖的最后一块砖,换句话说 4 和 6 不能是刚好铺满 2 _ N 的最后一块瓷砖。
为了方便描述,我们令 F(n) 表示刚好铺满 2 * n 的瓷砖的总的可能数,因此题目要求的其实就是 F(n)。
如果最后一块选择了形状 1,那么此时的刚好铺满 2 * n 的瓷砖的总的可能数是 F(n-2)
如果最后一块选择了形状 2,那么此时的刚好铺满 2 * n 的瓷砖的总的可能数是 F(n-1)
如果最后一块选择了形状 3,那么此时的刚好铺满 2 * n 的瓷砖的总的可能数是 ?
如果最后一块选择了形状 5,那么此时的刚好铺满 2 * n 的瓷砖的总的可能数是 ?
如果最后一块选择了形状 4 和 6,那么此时的刚好铺满 2 * n 的瓷砖的总的可能数是 0。换句话说 4 和 6 不可能是刚好铺满的最后一块砖。
虽然 4 和 6 不可能是刚好铺满的最后一块砖,但其实可以是中间状态,中间状态可以进一步转移到刚好铺满的状态。比如股票问题就是这样,虽然我们的最终答案不可能是买入之后,一定是卖出,但是中间的过程可以卖出,通过卖出转移到最终状态。
现在的问题是如何计算:最后一块选择了形状 3 和 最后一块选择了形状 5 的总的可能数,以及 4 和 6 在什么情况下选择。实际上,我们只需要考虑选择我 3 和 5 的总的可能数就行了,其原因稍后你就知道了。
为了表示所有的情况,我们需要另外一个状态定义和转移。 我们令 T(n) 表示刚好铺满 2 * (N - 1)瓷砖,最后一列只有一块瓷砖的总的可能数。对应上图中的 4 和 6。
经过这样的定义,那么就有:
如果倒数第二块选择了形状 4,那么最后一块选择形状 3 刚好铺满 2 * N 瓷砖。
如果倒数第二块选择了形状 6,那么最后一块选择形状 5 刚好铺满 2 * N 瓷砖。
大家可以根据基本图形画一下试试就知道了。同时你也应该理解了 4 和 6 在什么情况下使用。
根据以上的信息有如下公式:
由于上述等式有两个变量,因此至少需要两个这样的等式才可解。而上面的等式是 F(n) = xxx,因此一个直觉找到一个类似 T(n) = xxx 的公式。不难发现如下等式:
乘以 2 是因为最后一块可以选择 4 或者 6 任意一块
将上面两个公式进行合并。具体来说就是:
将 ④ 代入 ① 得:
至此,我们得出了状态转移方程:
关键点
识别最优子结构
对一块瓷砖能拼成的图形进行分解,并对每一种情况进行讨论
代码
语言支持:Python3
Python3 Code:
复杂度分析
令 n 为数组长度。
时间复杂度:$O(n)$
空间复杂度:$O(n)$
使用滚动数组优化可以将空间复杂度降低到 $O(1)$,大家可以试试。
此题解由 力扣刷题插件 自动生成。
力扣的小伙伴可以关注我,这样就会第一时间收到我的动态啦~
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
最后更新于