Domino and Tromino Tiling
Domino and Tromino Tiling is LeetCode 790 (Medium). You have a 2 × n board and an unlimited supply of two pieces: a 2 × 1 domino and an L-shaped tromino that covers three cells. Both pieces may be rotated. Return the number of ways to cover every cell exactly once, modulo 10⁹ + 7.
- Two tilings are different if some pair of neighbouring cells is covered by a single piece in one tiling but not in the other.
ngoes up to 1000, so the count is far too large to build tilings one by one.
- 1 <= n <= 1000
- Return the answer modulo 10⁹ + 7.
Intuition
Build the board from left to right and watch its right edge. With dominoes alone the edge is always flat. A tromino changes that: it can leave the last column with one cell covered and one empty.
So keep two counts for every width i:
- full[i]: tilings of a 2 ×
iboard with a flat right edge. - part[i]: tilings where column
ihas only its top cell covered. The version with only the bottom cell is its mirror image, so it has the same count.
Every tiling has one piece covering its last cell, and removing that piece leaves a smaller board of one of these two shapes. Adding up the choices for that last piece gives each count from smaller ones.
Counting the ways to tile a narrow strip is dynamic programming over the strip's length. When some piece can leave a jagged boundary, add one table per boundary shape; the same idea scales up to tiling a 3 × n or 4 × n board.
Approach
Before reading on: draw a 2 × 3 board and find all five tilings by hand. Then put one tromino at the left end of a long board and sketch the edge it leaves. Which counts would let you finish that board? Aim for O(n).
Two ways to solve it
Count boards with a flat right edge and boards with one stray cell.
- Derivable: each term comes from one possible last piece.
- Checkable: small widths are easy to verify by drawing.
The answer to give when you have to explain it.
One table and one line in the loop.
- Short: seeds 1, 1, 2, then a single update.
- Watch out: it is hard to justify without the two tables behind it.
Pick it once you know where it comes from.
Both run in O(n). The two-table version is the one you can build from scratch in an interview, so the steps, code and live demo follow it; the shorter recurrence is derived from it after the demo.
Seed widths 0 and 1
Set full[0] = 1 and full[1] = 1, and leave part[0] and part[1] at 0. A width-0 board has one tiling, placing nothing, and a single column fits only an upright domino. Starting from width 0 means no special case for small n.
Count boards with a flat edge
full[i] = full[i-1] + full[i-2] + 2 * part[i-1], sorted by the piece covering the bottom-right cell:
- an upright domino, on top of a full board of width
i-1; - a flat domino, which forces a second flat domino above it, on a full board of width
i-2; - a tromino, which completes a ragged board of width
i-1whose stray cell is on the top or the bottom, hence the 2.
Count boards with a ragged edge
part[i] = part[i-1] + full[i-2], sorted by the piece covering the top cell of column i:
- a flat domino across the top of columns
i-1andi, on a ragged board of widthi-1with its stray cell at the bottom; - a tromino filling column
i-1and the top of columni, on a full board of widthi-2.
Take the remainder inside the loop
Apply % MOD to both entries as they are computed, then return full[n]. The counts roughly double with each column, so a 64-bit integer overflows long before width 1000.
Domino and Tromino Tiling solution in Python | C++ | Java
One recurrence
Write the flat-edge formula for width n and for width n − 1, and subtract:
- the
fullterms leavefull[n−1] − full[n−3]; - the
partterms leave2 × (part[n−1] − part[n−2]), and the ragged-edge formula says that difference isfull[n−3].
Adding up gives full[n] = 2 × full[n−1] + full[n−3], with full[0] = 1, full[1] = 1, full[2] = 2. For n = 4: 2 × 5 + 1 = 11.
Common pitfalls
Counting full boards only
full[i] = full[i - 1] + full[i - 2]
full[i] = full[i - 1] + full[i - 2] + 2 * part[i - 1]
This is the domino-only count, which follows the Fibonacci numbers. For n = 3 it returns 3, but the answer is 5: the two tilings made of two trominoes are never counted.
Counting one tromino orientation
full[i] = full[i - 1] + full[i - 2] + part[i - 1]
full[i] = full[i - 1] + full[i - 2] + 2 * part[i - 1]
part only counts boards whose stray cell is on top. The boards with the stray cell at the bottom are just as many, and a tromino completes those too. Without the 2, n = 3 returns 4.
Starting the empty board at 0
full[0] = 0
full[0] = 1
Width 2 is built partly from width 0: two flat dominoes on an empty board. With full[0] = 0 that tiling disappears, and n = 2 returns 1 instead of 2.
Complexity
Domino and Tromino Tiling FAQ
Can it be solved faster than O(n)?
Yes. The one-line recurrence f(n) = 2f(n−1) + f(n−3) is linear, so it can be written as a 3 × 3 matrix [[2, 0, 1], [1, 0, 0], [0, 1, 0]] applied to (f(n−1), f(n−2), f(n−3)). Raising that matrix to a power by repeated squaring gives O(log n). With n at most 1000 it is not needed here.
What if only dominoes are allowed?
Then the edge is always flat, part is always 0, and full[i] = full[i−1] + full[i−2]: the Fibonacci numbers, 1, 1, 2, 3, 5, 8 and so on. That is the same count as the number of ways to climb n stairs taking one or two steps at a time.