Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.2209 #4088

Merged
merged 1 commit into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,19 @@ tags:

### 方法一:记忆化搜索

我们设计一个函数 $dfs(i, j)$ 表示从下标 $i$ 开始,使用 $j$ 条地毯,最少有多少个白色砖块没有被覆盖。答案即为 $dfs(0, numCarpets)$。
我们设计一个函数 $\textit{dfs}(i, j)$ 表示从下标 $i$ 开始,使用 $j$ 条地毯,最少有多少个白色砖块没有被覆盖。答案即为 $\textit{dfs}(0, \textit{numCarpets})$。

对于下标 $i$,我们分情况讨论:

- 如果 $i \ge n$,说明已经覆盖完所有砖块,返回 $0$;
- 如果 $floor[i] = 0$,则不需要使用地毯,直接跳过即可,即 $dfs(i, j) = dfs(i + 1, j)$;
- 如果 $j = 0$,那么我们可以直接利用前缀和数组 $s$ 计算出剩余未被覆盖的白色砖块的数目,即 $dfs(i, j) = s[n] - s[i]$;
- 如果 $floor[i] = 1$,那么我们可以选择使用地毯覆盖,也可以选择不使用地毯覆盖,取两者的最小值即可,即 $dfs(i, j) = min(dfs(i + 1, j), dfs(i + carpetLen, j - 1))$。
- 如果 $\textit{floor}[i] = 0$,则不需要使用地毯,直接跳过即可,即 $\textit{dfs}(i, j) = \textit{dfs}(i + 1, j)$;
- 如果 $j = 0$,那么我们可以直接利用前缀和数组 $s$ 计算出剩余未被覆盖的白色砖块的数目,即 $\textit{dfs}(i, j) = s[n] - s[i]$;
- 如果 $\textit{floor}[i] = 1$,那么我们可以选择使用地毯覆盖,也可以选择不使用地毯覆盖,取两者的最小值即可,即 $\textit{dfs}(i, j) = \min(\textit{dfs}(i + 1,
j), \textit{dfs}(i + \textit{carpetLen}, j - 1))$。

记忆化搜索即可。

时间复杂度 $O(n\times m)$,空间复杂度 $O(n\times m)$。其中 $n$ 和 $m$ 分别为字符串 $floor$ 的长度和 $numCarpets$ 的值。
时间复杂度 $O(n\times m)$,空间复杂度 $O(n\times m)$。其中 $n$ 和 $m$ 分别为字符串 $\textit{floor}$ 的长度和 $\textit{numCarpets}$ 的值。

<!-- tabs:start -->

Expand All @@ -94,10 +95,10 @@ tags:
class Solution:
def minimumWhiteTiles(self, floor: str, numCarpets: int, carpetLen: int) -> int:
@cache
def dfs(i, j):
def dfs(i: int, j: int) -> int:
if i >= n:
return 0
if floor[i] == '0':
if floor[i] == "0":
return dfs(i + 1, j)
if j == 0:
return s[-1] - s[i]
Expand All @@ -106,7 +107,7 @@ class Solution:
n = len(floor)
s = [0] * (n + 1)
for i, c in enumerate(floor):
s[i + 1] = s[i] + int(c == '1')
s[i + 1] = s[i] + int(c == "1")
ans = dfs(0, numCarpets)
dfs.cache_clear()
return ans
Expand All @@ -116,17 +117,14 @@ class Solution:

```java
class Solution {
private int[][] f;
private Integer[][] f;
private int[] s;
private int n;
private int k;

public int minimumWhiteTiles(String floor, int numCarpets, int carpetLen) {
n = floor.length();
f = new int[n][numCarpets + 1];
for (var e : f) {
Arrays.fill(e, -1);
}
f = new Integer[n][numCarpets + 1];
s = new int[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor.charAt(i) == '1' ? 1 : 0);
Expand All @@ -142,7 +140,7 @@ class Solution {
if (j == 0) {
return s[n] - s[i];
}
if (f[i][j] != -1) {
if (f[i][j] != null) {
return f[i][j];
}
if (s[i + 1] == s[i]) {
Expand All @@ -167,12 +165,19 @@ public:
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor[i] == '1');
}
function<int(int, int)> dfs;
dfs = [&](int i, int j) {
if (i >= n) return 0;
if (j == 0) return s[n] - s[i];
if (f[i][j] != -1) return f[i][j];
if (s[i + 1] == s[i]) return dfs(i + 1, j);
auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i >= n) {
return 0;
}
if (j == 0) {
return s[n] - s[i];
}
if (f[i][j] != -1) {
return f[i][j];
}
if (s[i + 1] == s[i]) {
return dfs(i + 1, j);
}
int ans = min(1 + dfs(i + 1, j), dfs(i + carpetLen, j - 1));
f[i][j] = ans;
return ans;
Expand Down Expand Up @@ -220,6 +225,37 @@ func minimumWhiteTiles(floor string, numCarpets int, carpetLen int) int {
}
```

#### TypeScript

```ts
function minimumWhiteTiles(floor: string, numCarpets: number, carpetLen: number): number {
const n = floor.length;
const f: number[][] = Array.from({ length: n }, () => Array(numCarpets + 1).fill(-1));
const s: number[] = Array(n + 1).fill(0);
for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor[i] === '1' ? 1 : 0);
}
const dfs = (i: number, j: number): number => {
if (i >= n) {
return 0;
}
if (j === 0) {
return s[n] - s[i];
}
if (f[i][j] !== -1) {
return f[i][j];
}
if (s[i + 1] === s[i]) {
return dfs(i + 1, j);
}
const ans = Math.min(1 + dfs(i + 1, j), dfs(i + carpetLen, j - 1));
f[i][j] = ans;
return ans;
};
return dfs(0, numCarpets);
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ tags:
<pre>
<strong>Input:</strong> floor = &quot;10110101&quot;, numCarpets = 2, carpetLen = 2
<strong>Output:</strong> 2
<strong>Explanation:</strong>
<strong>Explanation:</strong>
The figure above shows one way of covering the tiles with the carpets such that only 2 white tiles are visible.
No other way of covering the tiles with the carpets can leave less than 2 white tiles visible.
</pre>
Expand All @@ -47,7 +47,7 @@ No other way of covering the tiles with the carpets can leave less than 2 white
<pre>
<strong>Input:</strong> floor = &quot;11111&quot;, numCarpets = 2, carpetLen = 3
<strong>Output:</strong> 0
<strong>Explanation:</strong>
<strong>Explanation:</strong>
The figure above shows one way of covering the tiles with the carpets such that no white tiles are visible.
Note that the carpets are able to overlap one another.
</pre>
Expand All @@ -69,18 +69,18 @@ Note that the carpets are able to overlap one another.

### Solution 1: Memoization Search

Design a function $dfs(i, j)$ to represent the minimum number of white bricks that are not covered starting from index $i$ using $j$ carpets. The answer is $dfs(0, numCarpets)$.
We design a function $\textit{dfs}(i, j)$ to represent the minimum number of white tiles that are not covered starting from index $i$ using $j$ carpets. The answer is $\textit{dfs}(0, \textit{numCarpets})$.

For index $i$, we discuss different cases:
For index $i$, we discuss the following cases:

- If $i \ge n$, it means that all bricks have been covered, return $0$;
- If $floor[i] = 0$, there is no need to use a carpet, just skip it, that is, $dfs(i, j) = dfs(i + 1, j)$;
- If $j = 0$, we can directly calculate the number of remaining white bricks that have not been covered using the prefix sum array $s$, that is, $dfs(i, j) = s[n] - s[i]$;
- If $floor[i] = 1$, we can choose to use a carpet to cover it, or choose not to use a carpet to cover it, and take the minimum of the two, that is, $dfs(i, j) = min(dfs(i + 1, j), dfs(i + carpetLen, j - 1))$.
- If $i \ge n$, it means all tiles have been covered, return $0$;
- If $\textit{floor}[i] = 0$, then we do not need to use a carpet, just skip it, i.e., $\textit{dfs}(i, j) = \textit{dfs}(i + 1, j)$;
- If $j = 0$, then we can directly use the prefix sum array $s$ to calculate the number of remaining uncovered white tiles, i.e., $\textit{dfs}(i, j) = s[n] - s[i]$;
- If $\textit{floor}[i] = 1$, then we can choose to use a carpet or not, and take the minimum of the two, i.e., $\textit{dfs}(i, j) = \min(\textit{dfs}(i + 1, j), \textit{dfs}(i + \textit{carpetLen}, j - 1))$.

Use memoization search.
We use memoization search to solve this problem.

The time complexity is $O(n\times m)$, and the space complexity is $O(n\times m)$. Where $n$ and $m$ are the lengths of the string $floor$ and the value of $numCarpets$ respectively.
The time complexity is $O(n \times m)$, and the space complexity is $O(n \times m)$. Here, $n$ and $m$ are the length of the string $\textit{floor}$ and the value of $\textit{numCarpets}$, respectively.

<!-- tabs:start -->

Expand All @@ -90,10 +90,10 @@ The time complexity is $O(n\times m)$, and the space complexity is $O(n\times m)
class Solution:
def minimumWhiteTiles(self, floor: str, numCarpets: int, carpetLen: int) -> int:
@cache
def dfs(i, j):
def dfs(i: int, j: int) -> int:
if i >= n:
return 0
if floor[i] == '0':
if floor[i] == "0":
return dfs(i + 1, j)
if j == 0:
return s[-1] - s[i]
Expand All @@ -102,7 +102,7 @@ class Solution:
n = len(floor)
s = [0] * (n + 1)
for i, c in enumerate(floor):
s[i + 1] = s[i] + int(c == '1')
s[i + 1] = s[i] + int(c == "1")
ans = dfs(0, numCarpets)
dfs.cache_clear()
return ans
Expand All @@ -112,17 +112,14 @@ class Solution:

```java
class Solution {
private int[][] f;
private Integer[][] f;
private int[] s;
private int n;
private int k;

public int minimumWhiteTiles(String floor, int numCarpets, int carpetLen) {
n = floor.length();
f = new int[n][numCarpets + 1];
for (var e : f) {
Arrays.fill(e, -1);
}
f = new Integer[n][numCarpets + 1];
s = new int[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor.charAt(i) == '1' ? 1 : 0);
Expand All @@ -138,7 +135,7 @@ class Solution {
if (j == 0) {
return s[n] - s[i];
}
if (f[i][j] != -1) {
if (f[i][j] != null) {
return f[i][j];
}
if (s[i + 1] == s[i]) {
Expand All @@ -163,12 +160,19 @@ public:
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor[i] == '1');
}
function<int(int, int)> dfs;
dfs = [&](int i, int j) {
if (i >= n) return 0;
if (j == 0) return s[n] - s[i];
if (f[i][j] != -1) return f[i][j];
if (s[i + 1] == s[i]) return dfs(i + 1, j);
auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i >= n) {
return 0;
}
if (j == 0) {
return s[n] - s[i];
}
if (f[i][j] != -1) {
return f[i][j];
}
if (s[i + 1] == s[i]) {
return dfs(i + 1, j);
}
int ans = min(1 + dfs(i + 1, j), dfs(i + carpetLen, j - 1));
f[i][j] = ans;
return ans;
Expand Down Expand Up @@ -216,6 +220,37 @@ func minimumWhiteTiles(floor string, numCarpets int, carpetLen int) int {
}
```

#### TypeScript

```ts
function minimumWhiteTiles(floor: string, numCarpets: number, carpetLen: number): number {
const n = floor.length;
const f: number[][] = Array.from({ length: n }, () => Array(numCarpets + 1).fill(-1));
const s: number[] = Array(n + 1).fill(0);
for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor[i] === '1' ? 1 : 0);
}
const dfs = (i: number, j: number): number => {
if (i >= n) {
return 0;
}
if (j === 0) {
return s[n] - s[i];
}
if (f[i][j] !== -1) {
return f[i][j];
}
if (s[i + 1] === s[i]) {
return dfs(i + 1, j);
}
const ans = Math.min(1 + dfs(i + 1, j), dfs(i + carpetLen, j - 1));
f[i][j] = ans;
return ans;
};
return dfs(0, numCarpets);
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@ class Solution {
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor[i] == '1');
}
function<int(int, int)> dfs;
dfs = [&](int i, int j) {
if (i >= n) return 0;
if (j == 0) return s[n] - s[i];
if (f[i][j] != -1) return f[i][j];
if (s[i + 1] == s[i]) return dfs(i + 1, j);
auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i >= n) {
return 0;
}
if (j == 0) {
return s[n] - s[i];
}
if (f[i][j] != -1) {
return f[i][j];
}
if (s[i + 1] == s[i]) {
return dfs(i + 1, j);
}
int ans = min(1 + dfs(i + 1, j), dfs(i + carpetLen, j - 1));
f[i][j] = ans;
return ans;
};
return dfs(0, numCarpets);
}
};
};
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
class Solution {
private int[][] f;
private Integer[][] f;
private int[] s;
private int n;
private int k;

public int minimumWhiteTiles(String floor, int numCarpets, int carpetLen) {
n = floor.length();
f = new int[n][numCarpets + 1];
for (var e : f) {
Arrays.fill(e, -1);
}
f = new Integer[n][numCarpets + 1];
s = new int[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + (floor.charAt(i) == '1' ? 1 : 0);
Expand All @@ -25,7 +22,7 @@ private int dfs(int i, int j) {
if (j == 0) {
return s[n] - s[i];
}
if (f[i][j] != -1) {
if (f[i][j] != null) {
return f[i][j];
}
if (s[i + 1] == s[i]) {
Expand All @@ -35,4 +32,4 @@ private int dfs(int i, int j) {
f[i][j] = ans;
return ans;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class Solution:
def minimumWhiteTiles(self, floor: str, numCarpets: int, carpetLen: int) -> int:
@cache
def dfs(i, j):
def dfs(i: int, j: int) -> int:
if i >= n:
return 0
if floor[i] == '0':
if floor[i] == "0":
return dfs(i + 1, j)
if j == 0:
return s[-1] - s[i]
Expand All @@ -13,7 +13,7 @@ def dfs(i, j):
n = len(floor)
s = [0] * (n + 1)
for i, c in enumerate(floor):
s[i + 1] = s[i] + int(c == '1')
s[i + 1] = s[i] + int(c == "1")
ans = dfs(0, numCarpets)
dfs.cache_clear()
return ans
Loading
Loading