Skip to content

Commit 393ad81

Browse files
authored
Merge pull request #14 from iamAntimPal/Leetcode-75
Leetcode 75
2 parents 2ce9026 + 175b2a7 commit 393ad81

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def numTilings(self, n: int) -> int:
3+
f = [1, 0, 0, 0]
4+
mod = 10**9 + 7
5+
for i in range(1, n + 1):
6+
g = [0] * 4
7+
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
8+
g[1] = (f[2] + f[3]) % mod
9+
g[2] = (f[1] + f[3]) % mod
10+
g[3] = f[0]
11+
f = g
12+
return f[0]
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<!-- problem:start -->
2+
3+
# [790. Domino and Tromino Tiling](https://leetcode.com/problems/domino-and-tromino-tiling)
4+
5+
---
6+
- **comments**: true
7+
- **difficulty**: Medium
8+
- **tags**:
9+
- Dynamic Programming
10+
---
11+
12+
## Description
13+
14+
<!-- description:start -->
15+
16+
<p>You have two types of tiles: a <code>2 x 1</code> domino shape and a tromino shape. You may rotate these shapes.</p>
17+
<img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/0700-0799/0790.Domino%20and%20Tromino%20Tiling/images/lc-domino.jpg" style="width: 362px; height: 195px;" />
18+
<p>Given an integer n, return <em>the number of ways to tile an</em> <code>2 x n</code> <em>board</em>. Since the answer may be very large, return it <strong>modulo</strong> <code>10<sup>9</sup> + 7</code>.</p>
19+
20+
<p>In a tiling, every square must be covered by a tile. Two tilings are different if and only if there are two 4-directionally adjacent cells on the board such that exactly one of the tilings has both squares occupied by a tile.</p>
21+
22+
<p>&nbsp;</p>
23+
<p><strong class="example">Example 1:</strong></p>
24+
<img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/0700-0799/0790.Domino%20and%20Tromino%20Tiling/images/lc-domino1.jpg" style="width: 500px; height: 226px;" />
25+
<pre>
26+
<strong>Input:</strong> n = 3
27+
<strong>Output:</strong> 5
28+
<strong>Explanation:</strong> The five different ways are show above.
29+
</pre>
30+
31+
<p><strong class="example">Example 2:</strong></p>
32+
33+
<pre>
34+
<strong>Input:</strong> n = 1
35+
<strong>Output:</strong> 1
36+
</pre>
37+
38+
<p>&nbsp;</p>
39+
<p><strong>Constraints:</strong></p>
40+
41+
<ul>
42+
<li><code>1 &lt;= n &lt;= 1000</code></li>
43+
</ul>
44+
45+
<!-- description:end -->
46+
47+
## Solutions
48+
49+
<!-- solution:start -->
50+
51+
### Solution 1: Dynamic Programming
52+
53+
First, we need to understand the problem. The problem is essentially asking us to find the number of ways to tile a $2 \times n$ board, where each square on the board can only be covered by one tile.
54+
55+
There are two types of tiles: `2 x 1` and `L` shapes, and both types of tiles can be rotated. We denote the rotated tiles as `1 x 2` and `L'` shapes.
56+
57+
We define $f[i][j]$ to represent the number of ways to tile the first $2 \times i$ board, where $j$ represents the state of the last column. The last column has 4 states:
58+
59+
- The last column is fully covered, denoted as $0$
60+
- The last column has only the top square covered, denoted as $1$
61+
- The last column has only the bottom square covered, denoted as $2$
62+
- The last column is not covered, denoted as $3$
63+
64+
The answer is $f[n][0]$. Initially, $f[0][0] = 1$ and the rest $f[0][j] = 0$.
65+
66+
We consider tiling up to the $i$-th column and look at the state transition equations:
67+
68+
When $j = 0$, the last column is fully covered. It can be transitioned from the previous column's states $0, 1, 2, 3$ by placing the corresponding tiles, i.e., $f[i-1][0]$ with a `1 x 2` tile, $f[i-1][1]$ with an `L'` tile, $f[i-1][2]$ with an `L'` tile, or $f[i-1][3]$ with two `2 x 1` tiles. Therefore, $f[i][0] = \sum_{j=0}^3 f[i-1][j]$.
69+
70+
When $j = 1$, the last column has only the top square covered. It can be transitioned from the previous column's states $2, 3$ by placing a `2 x 1` tile or an `L` tile. Therefore, $f[i][1] = f[i-1][2] + f[i-1][3]$.
71+
72+
When $j = 2$, the last column has only the bottom square covered. It can be transitioned from the previous column's states $1, 3$ by placing a `2 x 1` tile or an `L'` tile. Therefore, $f[i][2] = f[i-1][1] + f[i-1][3]$.
73+
74+
When $j = 3$, the last column is not covered. It can be transitioned from the previous column's state $0$. Therefore, $f[i][3] = f[i-1][0]$.
75+
76+
We can see that the state transition equations only involve the previous column's states, so we can use a rolling array to optimize the space complexity.
77+
78+
Note that the values of the states can be very large, so we need to take modulo $10^9 + 7$.
79+
80+
The time complexity is $O(n)$, and the space complexity is $O(1)$. Where $n$ is the number of columns of the board.
81+
82+
<!-- tabs:start -->
83+
84+
#### Python3
85+
86+
```python
87+
class Solution:
88+
def numTilings(self, n: int) -> int:
89+
f = [1, 0, 0, 0]
90+
mod = 10**9 + 7
91+
for i in range(1, n + 1):
92+
g = [0] * 4
93+
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
94+
g[1] = (f[2] + f[3]) % mod
95+
g[2] = (f[1] + f[3]) % mod
96+
g[3] = f[0]
97+
f = g
98+
return f[0]
99+
```
100+
101+
#### Java
102+
103+
```java
104+
class Solution {
105+
public int numTilings(int n) {
106+
long[] f = {1, 0, 0, 0};
107+
int mod = (int) 1e9 + 7;
108+
for (int i = 1; i <= n; ++i) {
109+
long[] g = new long[4];
110+
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod;
111+
g[1] = (f[2] + f[3]) % mod;
112+
g[2] = (f[1] + f[3]) % mod;
113+
g[3] = f[0];
114+
f = g;
115+
}
116+
return (int) f[0];
117+
}
118+
}
119+
```
120+
121+
#### C++
122+
123+
```cpp
124+
class Solution {
125+
public:
126+
const int mod = 1e9 + 7;
127+
128+
int numTilings(int n) {
129+
long f[4] = {1, 0, 0, 0};
130+
for (int i = 1; i <= n; ++i) {
131+
long g[4] = {0, 0, 0, 0};
132+
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod;
133+
g[1] = (f[2] + f[3]) % mod;
134+
g[2] = (f[1] + f[3]) % mod;
135+
g[3] = f[0];
136+
memcpy(f, g, sizeof(g));
137+
}
138+
return f[0];
139+
}
140+
};
141+
```
142+
143+
#### Go
144+
145+
```go
146+
func numTilings(n int) int {
147+
f := [4]int{}
148+
f[0] = 1
149+
const mod int = 1e9 + 7
150+
for i := 1; i <= n; i++ {
151+
g := [4]int{}
152+
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
153+
g[1] = (f[2] + f[3]) % mod
154+
g[2] = (f[1] + f[3]) % mod
155+
g[3] = f[0]
156+
f = g
157+
}
158+
return f[0]
159+
}
160+
```
161+
162+
<!-- tabs:end -->
163+
164+
<!-- solution:end -->
165+
166+
<!-- problem:end -->

0 commit comments

Comments
 (0)