diff --git a/solution/0700-0799/0781.Rabbits in Forest/README.md b/solution/0700-0799/0781.Rabbits in Forest/README.md
index b1669c7a8f61d..7ee81866b1060 100644
--- a/solution/0700-0799/0781.Rabbits in Forest/README.md
+++ b/solution/0700-0799/0781.Rabbits in Forest/README.md
@@ -31,10 +31,10 @@ tags:
输入:answers = [1,1,2]
输出:5
解释:
-两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
+两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
之后回答了 "2" 的兔子不会是红色,否则他们的回答会相互矛盾。
-设回答了 "2" 的兔子为蓝色。
-此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
+设回答了 "2" 的兔子为蓝色。
+此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
因此森林中兔子的最少数量是 5 只:3 只回答的和 2 只没有回答的。
@@ -60,7 +60,13 @@ tags:
-### 方法一
+### 方法一:贪心 + 哈希表
+
+根据题目描述,回答相同的兔子,可能属于同一种颜色,而回答不同的兔子,不可能属于同一种颜色。
+
+因此,我们用一个哈希表 $\textit{cnt}$ 记录每种回答出现的次数。对于每种回答 $x$ 及其出现次数 $v$,我们按照每种颜色有 $x + 1$ 只兔子的原则,计算出兔子的最少数量,并将其加入答案。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{answers}$ 的长度。
@@ -69,8 +75,12 @@ tags:
```python
class Solution:
def numRabbits(self, answers: List[int]) -> int:
- counter = Counter(answers)
- return sum([math.ceil(v / (k + 1)) * (k + 1) for k, v in counter.items()])
+ cnt = Counter(answers)
+ ans = 0
+ for x, v in cnt.items():
+ group = x + 1
+ ans += (v + group - 1) // group * group
+ return ans
```
#### Java
@@ -78,17 +88,70 @@ class Solution:
```java
class Solution {
public int numRabbits(int[] answers) {
- Map counter = new HashMap<>();
- for (int e : answers) {
- counter.put(e, counter.getOrDefault(e, 0) + 1);
+ Map cnt = new HashMap<>();
+ for (int x : answers) {
+ cnt.merge(x, 1, Integer::sum);
}
- int res = 0;
- for (Map.Entry entry : counter.entrySet()) {
- int answer = entry.getKey(), count = entry.getValue();
- res += (int) Math.ceil(count / ((answer + 1) * 1.0)) * (answer + 1);
+ int ans = 0;
+ for (var e : cnt.entrySet()) {
+ int group = e.getKey() + 1;
+ ans += (e.getValue() + group - 1) / group * group;
+ }
+ return ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ int numRabbits(vector& answers) {
+ unordered_map cnt;
+ for (int x : answers) {
+ ++cnt[x];
}
- return res;
+ int ans = 0;
+ for (auto& [x, v] : cnt) {
+ int group = x + 1;
+ ans += (v + group - 1) / group * group;
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func numRabbits(answers []int) (ans int) {
+ cnt := map[int]int{}
+ for _, x := range answers {
+ cnt[x]++
+ }
+ for x, v := range cnt {
+ group := x + 1
+ ans += (v + group - 1) / group * group
+ }
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function numRabbits(answers: number[]): number {
+ const cnt = new Map();
+ for (const x of answers) {
+ cnt.set(x, (cnt.get(x) || 0) + 1);
+ }
+ let ans = 0;
+ for (const [x, v] of cnt.entries()) {
+ const group = x + 1;
+ ans += Math.floor((v + group - 1) / group) * group;
}
+ return ans;
}
```
diff --git a/solution/0700-0799/0781.Rabbits in Forest/README_EN.md b/solution/0700-0799/0781.Rabbits in Forest/README_EN.md
index 8b25ad8c980de..64c4163676514 100644
--- a/solution/0700-0799/0781.Rabbits in Forest/README_EN.md
+++ b/solution/0700-0799/0781.Rabbits in Forest/README_EN.md
@@ -58,7 +58,13 @@ The smallest possible number of rabbits in the forest is therefore 5: 3 that ans
-### Solution 1
+### Solution 1: Greedy + Hash Map
+
+According to the problem description, rabbits that give the same answer may belong to the same color, while rabbits that give different answers cannot belong to the same color.
+
+Therefore, we use a hash map $\textit{cnt}$ to record the number of occurrences of each answer. For each answer $x$ and its occurrence $v$, we calculate the minimum number of rabbits based on the principle that each color has $x + 1$ rabbits, and add it to the answer.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $\textit{answers}$.
@@ -67,8 +73,12 @@ The smallest possible number of rabbits in the forest is therefore 5: 3 that ans
```python
class Solution:
def numRabbits(self, answers: List[int]) -> int:
- counter = Counter(answers)
- return sum([math.ceil(v / (k + 1)) * (k + 1) for k, v in counter.items()])
+ cnt = Counter(answers)
+ ans = 0
+ for x, v in cnt.items():
+ group = x + 1
+ ans += (v + group - 1) // group * group
+ return ans
```
#### Java
@@ -76,17 +86,70 @@ class Solution:
```java
class Solution {
public int numRabbits(int[] answers) {
- Map counter = new HashMap<>();
- for (int e : answers) {
- counter.put(e, counter.getOrDefault(e, 0) + 1);
+ Map cnt = new HashMap<>();
+ for (int x : answers) {
+ cnt.merge(x, 1, Integer::sum);
}
- int res = 0;
- for (Map.Entry entry : counter.entrySet()) {
- int answer = entry.getKey(), count = entry.getValue();
- res += (int) Math.ceil(count / ((answer + 1) * 1.0)) * (answer + 1);
+ int ans = 0;
+ for (var e : cnt.entrySet()) {
+ int group = e.getKey() + 1;
+ ans += (e.getValue() + group - 1) / group * group;
+ }
+ return ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ int numRabbits(vector& answers) {
+ unordered_map cnt;
+ for (int x : answers) {
+ ++cnt[x];
}
- return res;
+ int ans = 0;
+ for (auto& [x, v] : cnt) {
+ int group = x + 1;
+ ans += (v + group - 1) / group * group;
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func numRabbits(answers []int) (ans int) {
+ cnt := map[int]int{}
+ for _, x := range answers {
+ cnt[x]++
+ }
+ for x, v := range cnt {
+ group := x + 1
+ ans += (v + group - 1) / group * group
+ }
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function numRabbits(answers: number[]): number {
+ const cnt = new Map();
+ for (const x of answers) {
+ cnt.set(x, (cnt.get(x) || 0) + 1);
+ }
+ let ans = 0;
+ for (const [x, v] of cnt.entries()) {
+ const group = x + 1;
+ ans += Math.floor((v + group - 1) / group) * group;
}
+ return ans;
}
```
diff --git a/solution/0700-0799/0781.Rabbits in Forest/Solution.cpp b/solution/0700-0799/0781.Rabbits in Forest/Solution.cpp
new file mode 100644
index 0000000000000..ececd01713f07
--- /dev/null
+++ b/solution/0700-0799/0781.Rabbits in Forest/Solution.cpp
@@ -0,0 +1,15 @@
+class Solution {
+public:
+ int numRabbits(vector& answers) {
+ unordered_map cnt;
+ for (int x : answers) {
+ ++cnt[x];
+ }
+ int ans = 0;
+ for (auto& [x, v] : cnt) {
+ int group = x + 1;
+ ans += (v + group - 1) / group * group;
+ }
+ return ans;
+ }
+};
diff --git a/solution/0700-0799/0781.Rabbits in Forest/Solution.go b/solution/0700-0799/0781.Rabbits in Forest/Solution.go
new file mode 100644
index 0000000000000..644d811e2ae85
--- /dev/null
+++ b/solution/0700-0799/0781.Rabbits in Forest/Solution.go
@@ -0,0 +1,11 @@
+func numRabbits(answers []int) (ans int) {
+ cnt := map[int]int{}
+ for _, x := range answers {
+ cnt[x]++
+ }
+ for x, v := range cnt {
+ group := x + 1
+ ans += (v + group - 1) / group * group
+ }
+ return
+}
diff --git a/solution/0700-0799/0781.Rabbits in Forest/Solution.java b/solution/0700-0799/0781.Rabbits in Forest/Solution.java
index 2552fdc28dc82..cf040daa2fdc5 100644
--- a/solution/0700-0799/0781.Rabbits in Forest/Solution.java
+++ b/solution/0700-0799/0781.Rabbits in Forest/Solution.java
@@ -1,14 +1,14 @@
class Solution {
public int numRabbits(int[] answers) {
- Map counter = new HashMap<>();
- for (int e : answers) {
- counter.put(e, counter.getOrDefault(e, 0) + 1);
+ Map cnt = new HashMap<>();
+ for (int x : answers) {
+ cnt.merge(x, 1, Integer::sum);
}
- int res = 0;
- for (Map.Entry entry : counter.entrySet()) {
- int answer = entry.getKey(), count = entry.getValue();
- res += (int) Math.ceil(count / ((answer + 1) * 1.0)) * (answer + 1);
+ int ans = 0;
+ for (var e : cnt.entrySet()) {
+ int group = e.getKey() + 1;
+ ans += (e.getValue() + group - 1) / group * group;
}
- return res;
+ return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0700-0799/0781.Rabbits in Forest/Solution.py b/solution/0700-0799/0781.Rabbits in Forest/Solution.py
index 9adfd9193eb15..cb2b04405ae8c 100644
--- a/solution/0700-0799/0781.Rabbits in Forest/Solution.py
+++ b/solution/0700-0799/0781.Rabbits in Forest/Solution.py
@@ -1,4 +1,8 @@
class Solution:
def numRabbits(self, answers: List[int]) -> int:
- counter = Counter(answers)
- return sum([math.ceil(v / (k + 1)) * (k + 1) for k, v in counter.items()])
+ cnt = Counter(answers)
+ ans = 0
+ for x, v in cnt.items():
+ group = x + 1
+ ans += (v + group - 1) // group * group
+ return ans
diff --git a/solution/0700-0799/0781.Rabbits in Forest/Solution.ts b/solution/0700-0799/0781.Rabbits in Forest/Solution.ts
new file mode 100644
index 0000000000000..3093c0bce6399
--- /dev/null
+++ b/solution/0700-0799/0781.Rabbits in Forest/Solution.ts
@@ -0,0 +1,12 @@
+function numRabbits(answers: number[]): number {
+ const cnt = new Map();
+ for (const x of answers) {
+ cnt.set(x, (cnt.get(x) || 0) + 1);
+ }
+ let ans = 0;
+ for (const [x, v] of cnt.entries()) {
+ const group = x + 1;
+ ans += Math.floor((v + group - 1) / group) * group;
+ }
+ return ans;
+}
diff --git a/solution/0700-0799/0790.Domino and Tromino Tiling/README.md b/solution/0700-0799/0790.Domino and Tromino Tiling/README.md
index 91eb9e51d0ee0..da30ee9b60a10 100644
--- a/solution/0700-0799/0790.Domino and Tromino Tiling/README.md
+++ b/solution/0700-0799/0790.Domino and Tromino Tiling/README.md
@@ -95,28 +95,16 @@ tags:
```python
class Solution:
def numTilings(self, n: int) -> int:
- @cache
- def dfs(i, j):
- if i > n or j > n:
- return 0
- if i == n and j == n:
- return 1
- ans = 0
- if i == j:
- ans = (
- dfs(i + 2, j + 2)
- + dfs(i + 1, j + 1)
- + dfs(i + 2, j + 1)
- + dfs(i + 1, j + 2)
- )
- elif i > j:
- ans = dfs(i, j + 2) + dfs(i + 1, j + 2)
- else:
- ans = dfs(i + 2, j) + dfs(i + 2, j + 1)
- return ans % mod
-
+ f = [1, 0, 0, 0]
mod = 10**9 + 7
- return dfs(0, 0)
+ for i in range(1, n + 1):
+ g = [0] * 4
+ g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
+ g[1] = (f[2] + f[3]) % mod
+ g[2] = (f[1] + f[3]) % mod
+ g[3] = f[0]
+ f = g
+ return f[0]
```
#### Java
@@ -184,31 +172,4 @@ func numTilings(n int) int {
-
-
-### 方法二
-
-
-
-#### Python3
-
-```python
-class Solution:
- def numTilings(self, n: int) -> int:
- f = [1, 0, 0, 0]
- mod = 10**9 + 7
- for i in range(1, n + 1):
- g = [0] * 4
- g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
- g[1] = (f[2] + f[3]) % mod
- g[2] = (f[1] + f[3]) % mod
- g[3] = f[0]
- f = g
- return f[0]
-```
-
-
-
-
-
diff --git a/solution/0700-0799/0790.Domino and Tromino Tiling/README_EN.md b/solution/0700-0799/0790.Domino and Tromino Tiling/README_EN.md
index 49dcfa9bb1f6f..04f89b3e86cd6 100644
--- a/solution/0700-0799/0790.Domino and Tromino Tiling/README_EN.md
+++ b/solution/0700-0799/0790.Domino and Tromino Tiling/README_EN.md
@@ -51,7 +51,36 @@ tags:
-### Solution 1
+### Solution 1: Dynamic Programming
+
+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.
+
+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.
+
+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:
+
+- The last column is fully covered, denoted as $0$
+- The last column has only the top square covered, denoted as $1$
+- The last column has only the bottom square covered, denoted as $2$
+- The last column is not covered, denoted as $3$
+
+The answer is $f[n][0]$. Initially, $f[0][0] = 1$ and the rest $f[0][j] = 0$.
+
+We consider tiling up to the $i$-th column and look at the state transition equations:
+
+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]$.
+
+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]$.
+
+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]$.
+
+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]$.
+
+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.
+
+Note that the values of the states can be very large, so we need to take modulo $10^9 + 7$.
+
+The time complexity is $O(n)$, and the space complexity is $O(1)$. Where $n$ is the number of columns of the board.
@@ -60,28 +89,16 @@ tags:
```python
class Solution:
def numTilings(self, n: int) -> int:
- @cache
- def dfs(i, j):
- if i > n or j > n:
- return 0
- if i == n and j == n:
- return 1
- ans = 0
- if i == j:
- ans = (
- dfs(i + 2, j + 2)
- + dfs(i + 1, j + 1)
- + dfs(i + 2, j + 1)
- + dfs(i + 1, j + 2)
- )
- elif i > j:
- ans = dfs(i, j + 2) + dfs(i + 1, j + 2)
- else:
- ans = dfs(i + 2, j) + dfs(i + 2, j + 1)
- return ans % mod
-
+ f = [1, 0, 0, 0]
mod = 10**9 + 7
- return dfs(0, 0)
+ for i in range(1, n + 1):
+ g = [0] * 4
+ g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
+ g[1] = (f[2] + f[3]) % mod
+ g[2] = (f[1] + f[3]) % mod
+ g[3] = f[0]
+ f = g
+ return f[0]
```
#### Java
@@ -149,31 +166,4 @@ func numTilings(n int) int {
-
-
-### Solution 2
-
-
-
-#### Python3
-
-```python
-class Solution:
- def numTilings(self, n: int) -> int:
- f = [1, 0, 0, 0]
- mod = 10**9 + 7
- for i in range(1, n + 1):
- g = [0] * 4
- g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
- g[1] = (f[2] + f[3]) % mod
- g[2] = (f[1] + f[3]) % mod
- g[3] = f[0]
- f = g
- return f[0]
-```
-
-
-
-
-
diff --git a/solution/0700-0799/0790.Domino and Tromino Tiling/Solution.py b/solution/0700-0799/0790.Domino and Tromino Tiling/Solution.py
index 2e2a27e3d0a64..39bb58c8e9dcc 100644
--- a/solution/0700-0799/0790.Domino and Tromino Tiling/Solution.py
+++ b/solution/0700-0799/0790.Domino and Tromino Tiling/Solution.py
@@ -1,24 +1,12 @@
class Solution:
def numTilings(self, n: int) -> int:
- @cache
- def dfs(i, j):
- if i > n or j > n:
- return 0
- if i == n and j == n:
- return 1
- ans = 0
- if i == j:
- ans = (
- dfs(i + 2, j + 2)
- + dfs(i + 1, j + 1)
- + dfs(i + 2, j + 1)
- + dfs(i + 1, j + 2)
- )
- elif i > j:
- ans = dfs(i, j + 2) + dfs(i + 1, j + 2)
- else:
- ans = dfs(i + 2, j) + dfs(i + 2, j + 1)
- return ans % mod
-
+ f = [1, 0, 0, 0]
mod = 10**9 + 7
- return dfs(0, 0)
+ for i in range(1, n + 1):
+ g = [0] * 4
+ g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
+ g[1] = (f[2] + f[3]) % mod
+ g[2] = (f[1] + f[3]) % mod
+ g[3] = f[0]
+ f = g
+ return f[0]
diff --git a/solution/0700-0799/0790.Domino and Tromino Tiling/Solution2.py b/solution/0700-0799/0790.Domino and Tromino Tiling/Solution2.py
deleted file mode 100644
index 39bb58c8e9dcc..0000000000000
--- a/solution/0700-0799/0790.Domino and Tromino Tiling/Solution2.py
+++ /dev/null
@@ -1,12 +0,0 @@
-class Solution:
- def numTilings(self, n: int) -> int:
- f = [1, 0, 0, 0]
- mod = 10**9 + 7
- for i in range(1, n + 1):
- g = [0] * 4
- g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
- g[1] = (f[2] + f[3]) % mod
- g[2] = (f[1] + f[3]) % mod
- g[3] = f[0]
- f = g
- return f[0]