LeetCode Entry
790. Domino and Tromino Tiling
Ways to fill 2xn board with I,L shapes
790. Domino and Tromino Tiling meidum
blog post
substack
youtube

Join me on Telegram
https://t.me/leetcode_daily_unstoppable/979
Problem TLDR
Ways to fill 2xn board with I,L shapes #medium #dp
Intuition
Let’s full-search by trying every possible way of placing every domino shape at current position i with Depth-First Search. If the final column is filled, count this way as 1. Result only depends on the current position i and the column filled condition of 00 as empty, 01 as bottom filled and 10 as top filled. Can be cached.
Another fun way to optimize the solution is to look at the pattern of the results:
1
1
2
5
11 5 * 2 + 1
24 11 * 2 + 2
53 24 * 2 + 5
117 53 * 2 + 11
258
569
1255
2768
Approach
- for dp we can either go
i+2or introduce another filled state11 - there is also an O(log(n)) solution by doing matrix^n
// [ a_n ] [ 2 0 1 ] [ a_{n-1} ]
// [a_{n-1}] = [ 1 0 0 ] [ a_{n-2} ]
// [a_{n-2}] [ 0 1 0 ] [ a_{n-3} ]
Complexity
-
Time complexity: \(O(n)\)
-
Space complexity: \(O(n)\), or O(1) for the arithmetic solution
Code
// 6ms
fun numTilings(n: Int): Int {
val M = 1_000_000_007; val dp = HashMap<Pair<Int, Int>, Int>()
fun dfs(i: Int, tb: Int): Int = if (i > n) 0 else if (i == n)
{ if (tb == 0) 1 else 0 } else dp.getOrPut(i to tb) {
val vertical = if (tb > 0) 0 else dfs(i + 1, 0b00)
val horizontal = dfs(i + 2, 0b00)
val trtop = if (tb == 0b10) 0 else dfs(i + 1, 0b10)
val trbot = if (tb == 0b01) 0 else dfs(i + 1, 0b01)
(((vertical + horizontal) % M + trtop) % M + trbot) % M
}
return dfs(0, 0)
}
// 0ms
fun numTilings(n: Int): Int {
var a = 1; var b = 1; var c = 2; val m = 1000000007
for (i in 3..n) { val t = a; a = b; b = c; c = ((2 * b) % m + t) % m }
return if (n < 2) 1 else if (n < 3) 2 else c
}
// 0ms
pub fn num_tilings(n: i32) -> i32 {
let (mut a, mut b, mut c, m) = (1, 1, 2, 1000000007);
for i in 3..=n { (a, b, c) = (b, c, ((2 * c) % m + a) % m) }
if n < 2 { 1 } else if n < 3 { 2 } else { c }
}
// 0ms
int numTilings(int n) {
int c = 2;
for (int i = 3, t, a = 1, b = 1, m = 1e9+7; i <= n; ++i)
t = a, a = b, b = c, c = ((2 * b) % m + t) % m;
return n < 2 ? 1 : n < 3 ? 2 : c;
}