题目
有两种形状的瓷砖:一种是 2 x 1 的多米诺形,另一种是形如 "L" 的托米诺形。两种形状都可以旋转。
给定整数 n ,返回可以平铺 2 x n 的面板的方法的数量。返回对 109 + 7 取模 的值。
平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同,当且仅当面板上有四个方向上的相邻单元中的两个,使得恰好有一个平铺有一个瓷砖占据两个正方形。
一、代码实现(动态规划+滚动数组优化)
go
func numTilings(n int) int {
const mod = 1e9 + 7
if n == 0 {
return 1
}
if n <= 2 {
return []int{0, 1, 2}[n]
}
a, b, c := 1, 1, 2
for i := 3; i <= n; i++ {
next := (2*c + a) % mod
a, 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. 多语言实现
java
class Solution {
public int numTilings(int n) {
final int MOD = 1000000007;
if (n == 0) return 1;
if (n <= 2) return new int[]{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;
}
}
python
class Solution:
def numTilings(self, n: int) -> int:
MOD = 10**9 +7
if n ==0: return 1
if n <=2: return [0,1,2][n]
a, b, c = 1, 1, 2
for _ in range(3, n+1):
a, b, c = b, c, (2*c +a) % MOD
return c
五、总结与优化
1. 算法对比
方法 | 优势 | 适用场景 |
---|---|---|
动态规划 | 时间复杂度最优 | 常规场景 |
矩阵快速幂 | O(log n)时间复杂度 | 极大n值计算 |
记忆化递归 | 代码直观 | 小规模计算 |
2. 工程优化
- 预计算缓存:存储常用值加速重复查询
- 并行计算:分段计算合并结果
- SIMD优化:利用向量指令加速计算
3. 扩展方向
- 非对称瓷砖:处理不同尺寸瓷砖的组合
- 彩色铺法:考虑颜色搭配的排列组合
- 拓扑约束:引入连通性等拓扑限制条件