有两种形状的瓷砖:一种是 2 x 1 的多米诺形,另一种是形如 “L” 的托米诺形。两种形状都可以旋转。 给定整数 n ,返回可以平铺 2 x n 的面板的方法的数量。返回对 109 + 7 取模 的值。 平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同,当且仅当面板上有四个方向上的相邻单元中的两个,使得恰好有一个平铺有一个瓷砖占据两个正方形。
一、代码实现(动态规划+滚动数组优化)
funcnumTilings(n int)int{const mod =1e9+7if n ==0{return1}if n <=2{return[]int{0,1,2}[n]}a, b, c :=1,1,2for i :=3; i <= n; i++{next :=(2*c + a)% moda, b, c = b, c, next}return c
}
二、算法分析
1. 核心思路
递推关系:发现状态转移方程dp[n] = 2*dp[n-1] + dp[n-3]
滚动数组优化:仅维护前三个状态值降低空间复杂度
边界处理:直接处理n=0,1,2的特殊情况
2. 关键步骤
初始化状态:a=dp[0]=1, b=dp[1]=1, c=dp[2]=2
迭代计算:
根据递推式更新当前状态
滚动更新前三个状态值
结果返回:最终c即为所求值
3. 复杂度
指标
值
说明
时间复杂度
O(n)
线性遍历到目标位置
空间复杂度
O(1)
仅使用三个临时变量
三、图解示例
四、边界条件与扩展
1. 特殊场景验证
n=0:空面板返回1种方法
n=1:只能竖直铺多米诺返回1
n=2:两种铺法(两竖直/两水平)返回2
大数测试:验证模运算正确性
2. 扩展应用
三维铺砖:扩展到三维空间铺砖问题
动态瓷砖:处理可变形状瓷砖的铺法
艺术设计:生成具有美学的铺砖图案
3. 多语言实现
classSolution{publicintnumTilings(int n){finalint MOD =1000000007;if(n ==0)return1;if(n <=2)returnnewint[]{0,1,2}[n];int a =1, b =1, c =2;for(int i =3; i <= n; i++){int next =(2*c % MOD + a)% MOD;a = b;b = c;c = next;}return c;}}
classSolution:defnumTilings(self, n:int)->int:MOD =10**9+7if n ==0:return1if n <=2:return[0,1,2][n]a, b, c =1,1,2for _ inrange(3, n+1):a, b, c = b, c,(2*c +a)% MODreturn c