From 66f8ec0f91f7cecfec142f1cb79413d30286d73c Mon Sep 17 00:00:00 2001
From: acbin <44314231+acbin@users.noreply.github.com>
Date: Thu, 21 Dec 2023 08:51:30 +0800
Subject: [PATCH 1/2] feat: add new lc problem (#2133)
---
.../README.md | 98 +++++++++++++++++++
.../README_EN.md | 90 +++++++++++++++++
solution/README.md | 1 +
solution/README_EN.md | 1 +
solution/summary.md | 1 +
solution/summary_en.md | 1 +
6 files changed, 192 insertions(+)
create mode 100644 solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README.md
create mode 100644 solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README_EN.md
diff --git a/solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README.md b/solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README.md
new file mode 100644
index 0000000000000..050a765c6f095
--- /dev/null
+++ b/solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README.md
@@ -0,0 +1,98 @@
+# [2969. Minimum Number of Coins for Fruits II](https://leetcode.cn/problems/minimum-number-of-coins-for-fruits-ii)
+
+[English Version](/solution/2900-2999/2969.Minimum%20Number%20of%20Coins%20for%20Fruits%20II/README_EN.md)
+
+## 题目描述
+
+
+
+
You are at a fruit market with different types of exotic fruits on display.
+
+You are given a 1-indexed array prices
, where prices[i]
denotes the number of coins needed to purchase the ith
fruit.
+
+The fruit market has the following offer:
+
+
+ - If you purchase the
ith
fruit at prices[i]
coins, you can get the next i
fruits for free.
+
+
+Note that even if you can take fruit j
for free, you can still purchase it for prices[j]
coins to receive a new offer.
+
+Return the minimum number of coins needed to acquire all the fruits.
+
+
+Example 1:
+
+
+Input: prices = [3,1,2]
+Output: 4
+Explanation: You can acquire the fruits as follows:
+- Purchase the 1st fruit with 3 coins, and you are allowed to take the 2nd fruit for free.
+- Purchase the 2nd fruit with 1 coin, and you are allowed to take the 3rd fruit for free.
+- Take the 3rd fruit for free.
+Note that even though you were allowed to take the 2nd fruit for free, you purchased it because it is more optimal.
+It can be proven that 4 is the minimum number of coins needed to acquire all the fruits.
+
+
+Example 2:
+
+
+Input: prices = [1,10,1,1]
+Output: 2
+Explanation: You can acquire the fruits as follows:
+- Purchase the 1st fruit with 1 coin, and you are allowed to take the 2nd fruit for free.
+- Take the 2nd fruit for free.
+- Purchase the 3rd fruit for 1 coin, and you are allowed to take the 4th fruit for free.
+- Take the 4th fruit for free.
+It can be proven that 2 is the minimum number of coins needed to acquire all the fruits.
+
+
+
+Constraints:
+
+
+ 1 <= prices.length <= 105
+ 1 <= prices[i] <= 105
+
+
+## 解法
+
+
+
+
+
+### **Python3**
+
+
+
+```python
+
+```
+
+### **Java**
+
+
+
+```java
+
+```
+
+### **C++**
+
+```cpp
+
+```
+
+### **Go**
+
+```go
+
+```
+
+### **...**
+
+```
+
+```
+
+
diff --git a/solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README_EN.md b/solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README_EN.md
new file mode 100644
index 0000000000000..87c6ae17be4db
--- /dev/null
+++ b/solution/2900-2999/2969.Minimum Number of Coins for Fruits II/README_EN.md
@@ -0,0 +1,90 @@
+# [2969. Minimum Number of Coins for Fruits II](https://leetcode.com/problems/minimum-number-of-coins-for-fruits-ii)
+
+[中文文档](/solution/2900-2999/2969.Minimum%20Number%20of%20Coins%20for%20Fruits%20II/README.md)
+
+## Description
+
+You are at a fruit market with different types of exotic fruits on display.
+
+You are given a 1-indexed array prices
, where prices[i]
denotes the number of coins needed to purchase the ith
fruit.
+
+The fruit market has the following offer:
+
+
+ - If you purchase the
ith
fruit at prices[i]
coins, you can get the next i
fruits for free.
+
+
+Note that even if you can take fruit j
for free, you can still purchase it for prices[j]
coins to receive a new offer.
+
+Return the minimum number of coins needed to acquire all the fruits.
+
+
+Example 1:
+
+
+Input: prices = [3,1,2]
+Output: 4
+Explanation: You can acquire the fruits as follows:
+- Purchase the 1st fruit with 3 coins, and you are allowed to take the 2nd fruit for free.
+- Purchase the 2nd fruit with 1 coin, and you are allowed to take the 3rd fruit for free.
+- Take the 3rd fruit for free.
+Note that even though you were allowed to take the 2nd fruit for free, you purchased it because it is more optimal.
+It can be proven that 4 is the minimum number of coins needed to acquire all the fruits.
+
+
+Example 2:
+
+
+Input: prices = [1,10,1,1]
+Output: 2
+Explanation: You can acquire the fruits as follows:
+- Purchase the 1st fruit with 1 coin, and you are allowed to take the 2nd fruit for free.
+- Take the 2nd fruit for free.
+- Purchase the 3rd fruit for 1 coin, and you are allowed to take the 4th fruit for free.
+- Take the 4th fruit for free.
+It can be proven that 2 is the minimum number of coins needed to acquire all the fruits.
+
+
+
+Constraints:
+
+
+ 1 <= prices.length <= 105
+ 1 <= prices[i] <= 105
+
+
+## Solutions
+
+
+
+### **Python3**
+
+```python
+
+```
+
+### **Java**
+
+```java
+
+```
+
+### **C++**
+
+```cpp
+
+```
+
+### **Go**
+
+```go
+
+```
+
+### **...**
+
+```
+
+```
+
+
diff --git a/solution/README.md b/solution/README.md
index aea51e28c1ce8..92aebda9a4d27 100644
--- a/solution/README.md
+++ b/solution/README.md
@@ -2979,6 +2979,7 @@
| 2966 | [划分数组并满足最大差限制](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README.md) | | 中等 | 第 376 场周赛 |
| 2967 | [使数组成为等数数组的最小代价](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README.md) | | 中等 | 第 376 场周赛 |
| 2968 | [执行操作使频率分数最大](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README.md) | | 困难 | 第 376 场周赛 |
+| 2969 | [Minimum Number of Coins for Fruits II](/solution/2900-2999/2969.Minimum%20Number%20of%20Coins%20for%20Fruits%20II/README.md) | | 困难 | 🔒 |
## 版权
diff --git a/solution/README_EN.md b/solution/README_EN.md
index fbaba2fd8a2cf..7b5d9d2041d36 100644
--- a/solution/README_EN.md
+++ b/solution/README_EN.md
@@ -2977,6 +2977,7 @@ Press Control + F(or Command + F on
| 2966 | [Divide Array Into Arrays With Max Difference](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README_EN.md) | | Medium | Weekly Contest 376 |
| 2967 | [Minimum Cost to Make Array Equalindromic](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README_EN.md) | | Medium | Weekly Contest 376 |
| 2968 | [Apply Operations to Maximize Frequency Score](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README_EN.md) | | Hard | Weekly Contest 376 |
+| 2969 | [Minimum Number of Coins for Fruits II](/solution/2900-2999/2969.Minimum%20Number%20of%20Coins%20for%20Fruits%20II/README_EN.md) | | Hard | 🔒 |
## Copyright
diff --git a/solution/summary.md b/solution/summary.md
index 78016bbc0885b..2b755cca6ddff 100644
--- a/solution/summary.md
+++ b/solution/summary.md
@@ -3026,3 +3026,4 @@
- [2966.划分数组并满足最大差限制](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README.md)
- [2967.使数组成为等数数组的最小代价](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README.md)
- [2968.执行操作使频率分数最大](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README.md)
+ - [2969.Minimum Number of Coins for Fruits II](/solution/2900-2999/2969.Minimum%20Number%20of%20Coins%20for%20Fruits%20II/README.md)
diff --git a/solution/summary_en.md b/solution/summary_en.md
index 4a4cb39a6461a..20d4043d71baf 100644
--- a/solution/summary_en.md
+++ b/solution/summary_en.md
@@ -3026,3 +3026,4 @@
- [2966.Divide Array Into Arrays With Max Difference](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README_EN.md)
- [2967.Minimum Cost to Make Array Equalindromic](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README_EN.md)
- [2968.Apply Operations to Maximize Frequency Score](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README_EN.md)
+ - [2969.Minimum Number of Coins for Fruits II](/solution/2900-2999/2969.Minimum%20Number%20of%20Coins%20for%20Fruits%20II/README_EN.md)
From 64b25ee311c5ce489f7ceedf1811e5060ac3d07a Mon Sep 17 00:00:00 2001
From: Libin YANG
Date: Thu, 21 Dec 2023 08:58:18 +0800
Subject: [PATCH 2/2] feat: add solutions to lc problem: No.1778 (#2134)
No.1778.Shortest Path in a Hidden Grid
---
.../README.md | 163 ++++++++++++-----
.../README_EN.md | 165 +++++++++++++-----
.../Solution.cpp | 64 +++++++
.../Solution.java | 123 ++++++-------
.../Solution.py | 109 ++++++------
5 files changed, 408 insertions(+), 216 deletions(-)
create mode 100644 solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.cpp
diff --git a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README.md b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README.md
index 3ca2c4a1f077c..9bc5ec30c9ab8 100644
--- a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README.md
+++ b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README.md
@@ -92,7 +92,15 @@ The robot is initially standing on cell (1, 0), denoted by the -1.
**方法一:DFS 建图 + BFS 求最短路**
-相似题目:[1810. 隐藏网格下的最小消耗路径](/solution/1800-1899/1810.Minimum%20Path%20Cost%20in%20a%20Hidden%20Grid/README.md)
+我们不妨假设机器人从坐标 $(0, 0)$ 出发,那么我们可以通过 DFS,找到所有可达的坐标,记录在哈希表 $vis$ 中。另外,我们还需要记录终点的坐标 $target$。
+
+如果找不到终点,那么直接返回 $-1$。否则,我们可以通过 BFS,求出最短路。
+
+时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是网格的行数和列数。
+
+相似题目:
+
+- [1810. 隐藏网格下的最小消耗路径](/solution/1800-1899/1810.Minimum%20Path%20Cost%20in%20a%20Hidden%20Grid/README.md)
@@ -118,31 +126,28 @@ The robot is initially standing on cell (1, 0), denoted by the -1.
class Solution(object):
- def findShortestPath(self, master: 'GridMaster') -> int:
- def dfs(i, j):
- nonlocal target
+ def findShortestPath(self, master: "GridMaster") -> int:
+ def dfs(i: int, j: int):
if master.isTarget():
+ nonlocal target
target = (i, j)
- for dir, ndir, a, b in dirs:
- x, y = i + a, j + b
- if master.canMove(dir) and (x, y) not in s:
- s.add((x, y))
- master.move(dir)
+ return
+ for k, c in enumerate(s):
+ x, y = i + dirs[k], j + dirs[k + 1]
+ if master.canMove(c) and (x, y) not in vis:
+ vis.add((x, y))
+ master.move(c)
dfs(x, y)
- master.move(ndir)
+ master.move(s[(k + 2) % 4])
+ s = "URDL"
+ dirs = (-1, 0, 1, 0, -1)
target = None
- s = set()
- dirs = [
- ['U', 'D', -1, 0],
- ['D', 'U', 1, 0],
- ['L', 'R', 0, -1],
- ['R', 'L', 0, 1],
- ]
+ vis = set()
dfs(0, 0)
if target is None:
return -1
- s.remove((0, 0))
+ vis.discard((0, 0))
q = deque([(0, 0)])
ans = -1
while q:
@@ -151,10 +156,10 @@ class Solution(object):
i, j = q.popleft()
if (i, j) == target:
return ans
- for _, _, a, b in dirs:
+ for a, b in pairwise(dirs):
x, y = i + a, j + b
- if (x, y) in s:
- s.remove((x, y))
+ if (x, y) in vis:
+ vis.remove((x, y))
q.append((x, y))
return -1
```
@@ -175,37 +180,31 @@ class Solution(object):
*/
class Solution {
- private static final char[] dir = {'U', 'R', 'D', 'L'};
- private static final char[] ndir = {'D', 'L', 'U', 'R'};
- private static final int[] dirs = {-1, 0, 1, 0, -1};
- private static final int N = 1010;
- private Set s;
private int[] target;
+ private GridMaster master;
+ private final int n = 2010;
+ private final String s = "URDL";
+ private final int[] dirs = {-1, 0, 1, 0, -1};
+ private final Set vis = new HashSet<>();
public int findShortestPath(GridMaster master) {
- target = null;
- s = new HashSet<>();
- s.add(0);
- dfs(0, 0, master);
+ this.master = master;
+ dfs(0, 0);
if (target == null) {
return -1;
}
- s.remove(0);
+ vis.remove(0);
Deque q = new ArrayDeque<>();
q.offer(new int[] {0, 0});
- int ans = -1;
- while (!q.isEmpty()) {
- ++ans;
- for (int n = q.size(); n > 0; --n) {
- int[] p = q.poll();
- int i = p[0], j = p[1];
- if (target[0] == i && target[1] == j) {
+ for (int ans = 0; !q.isEmpty(); ++ans) {
+ for (int m = q.size(); m > 0; --m) {
+ var p = q.poll();
+ if (p[0] == target[0] && p[1] == target[1]) {
return ans;
}
for (int k = 0; k < 4; ++k) {
- int x = i + dirs[k], y = j + dirs[k + 1];
- if (s.contains(x * N + y)) {
- s.remove(x * N + y);
+ int x = p[0] + dirs[k], y = p[1] + dirs[k + 1];
+ if (vis.remove(x * n + y)) {
q.offer(new int[] {x, y});
}
}
@@ -214,24 +213,92 @@ class Solution {
return -1;
}
- private void dfs(int i, int j, GridMaster master) {
+ private void dfs(int i, int j) {
if (master.isTarget()) {
target = new int[] {i, j};
+ return;
}
for (int k = 0; k < 4; ++k) {
- char d = dir[k], nd = ndir[k];
int x = i + dirs[k], y = j + dirs[k + 1];
- if (master.canMove(d) && !s.contains(x * N + y)) {
- s.add(x * N + y);
- master.move(d);
- dfs(x, y, master);
- master.move(nd);
+ if (master.canMove(s.charAt(k)) && vis.add(x * n + y)) {
+ master.move(s.charAt(k));
+ dfs(x, y);
+ master.move(s.charAt((k + 2) % 4));
}
}
}
}
```
+### **C++**
+
+```cpp
+/**
+ * // This is the GridMaster's API interface.
+ * // You should not implement it, or speculate about its implementation
+ * class GridMaster {
+ * public:
+ * bool canMove(char direction);
+ * void move(char direction);
+ * boolean isTarget();
+ * };
+ */
+
+class Solution {
+private:
+ const int n = 2010;
+ int dirs[5] = {-1, 0, 1, 0, -1};
+ string s = "URDL";
+ int target;
+ unordered_set vis;
+
+public:
+ int findShortestPath(GridMaster& master) {
+ target = n * n;
+ vis.insert(0);
+ dfs(0, 0, master);
+ if (target == n * n) {
+ return -1;
+ }
+ vis.erase(0);
+ queue> q;
+ q.emplace(0, 0);
+ for (int ans = 0; q.size(); ++ans) {
+ for (int m = q.size(); m; --m) {
+ auto [i, j] = q.front();
+ q.pop();
+ if (i * n + j == target) {
+ return ans;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (vis.count(x * n + y)) {
+ vis.erase(x * n + y);
+ q.emplace(x, y);
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ void dfs(int i, int j, GridMaster& master) {
+ if (master.isTarget()) {
+ target = i * n + j;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (master.canMove(s[k]) && !vis.count(x * n + y)) {
+ vis.insert(x * n + y);
+ master.move(s[k]);
+ dfs(x, y, master);
+ master.move(s[(k + 2) % 4]);
+ }
+ }
+ }
+};
+```
+
### **...**
```
diff --git a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README_EN.md b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README_EN.md
index 22f5c949574da..4bac1d9e7321f 100644
--- a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README_EN.md
+++ b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/README_EN.md
@@ -86,6 +86,18 @@ We now know that the target is the cell (0, 1), and the shortest path to the tar
## Solutions
+**Solution 1: DFS for Graph Construction + BFS for Shortest Path**
+
+We can assume that the robot starts from the coordinate $(0, 0)$. Then, we can use DFS to find all reachable coordinates and record them in the hash table $vis$. In addition, we also need to record the coordinates of the endpoint $target$.
+
+If the endpoint cannot be found, we directly return $-1$. Otherwise, we can use BFS to find the shortest path.
+
+The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are the number of rows and columns of the grid, respectively.
+
+Similar problems:
+
+- [1810. Minimum Path Cost in a Hidden Grid](/solution/1800-1899/1810.Minimum%20Path%20Cost%20in%20a%20Hidden%20Grid/README_EN.md)
+
### **Python3**
@@ -108,31 +120,28 @@ We now know that the target is the cell (0, 1), and the shortest path to the tar
class Solution(object):
- def findShortestPath(self, master: 'GridMaster') -> int:
- def dfs(i, j):
- nonlocal target
+ def findShortestPath(self, master: "GridMaster") -> int:
+ def dfs(i: int, j: int):
if master.isTarget():
+ nonlocal target
target = (i, j)
- for dir, ndir, a, b in dirs:
- x, y = i + a, j + b
- if master.canMove(dir) and (x, y) not in s:
- s.add((x, y))
- master.move(dir)
+ return
+ for k, c in enumerate(s):
+ x, y = i + dirs[k], j + dirs[k + 1]
+ if master.canMove(c) and (x, y) not in vis:
+ vis.add((x, y))
+ master.move(c)
dfs(x, y)
- master.move(ndir)
+ master.move(s[(k + 2) % 4])
+ s = "URDL"
+ dirs = (-1, 0, 1, 0, -1)
target = None
- s = set()
- dirs = [
- ['U', 'D', -1, 0],
- ['D', 'U', 1, 0],
- ['L', 'R', 0, -1],
- ['R', 'L', 0, 1],
- ]
+ vis = set()
dfs(0, 0)
if target is None:
return -1
- s.remove((0, 0))
+ vis.discard((0, 0))
q = deque([(0, 0)])
ans = -1
while q:
@@ -141,10 +150,10 @@ class Solution(object):
i, j = q.popleft()
if (i, j) == target:
return ans
- for _, _, a, b in dirs:
+ for a, b in pairwise(dirs):
x, y = i + a, j + b
- if (x, y) in s:
- s.remove((x, y))
+ if (x, y) in vis:
+ vis.remove((x, y))
q.append((x, y))
return -1
```
@@ -163,37 +172,31 @@ class Solution(object):
*/
class Solution {
- private static final char[] dir = {'U', 'R', 'D', 'L'};
- private static final char[] ndir = {'D', 'L', 'U', 'R'};
- private static final int[] dirs = {-1, 0, 1, 0, -1};
- private static final int N = 1010;
- private Set s;
private int[] target;
+ private GridMaster master;
+ private final int n = 2010;
+ private final String s = "URDL";
+ private final int[] dirs = {-1, 0, 1, 0, -1};
+ private final Set vis = new HashSet<>();
public int findShortestPath(GridMaster master) {
- target = null;
- s = new HashSet<>();
- s.add(0);
- dfs(0, 0, master);
+ this.master = master;
+ dfs(0, 0);
if (target == null) {
return -1;
}
- s.remove(0);
+ vis.remove(0);
Deque q = new ArrayDeque<>();
q.offer(new int[] {0, 0});
- int ans = -1;
- while (!q.isEmpty()) {
- ++ans;
- for (int n = q.size(); n > 0; --n) {
- int[] p = q.poll();
- int i = p[0], j = p[1];
- if (target[0] == i && target[1] == j) {
+ for (int ans = 0; !q.isEmpty(); ++ans) {
+ for (int m = q.size(); m > 0; --m) {
+ var p = q.poll();
+ if (p[0] == target[0] && p[1] == target[1]) {
return ans;
}
for (int k = 0; k < 4; ++k) {
- int x = i + dirs[k], y = j + dirs[k + 1];
- if (s.contains(x * N + y)) {
- s.remove(x * N + y);
+ int x = p[0] + dirs[k], y = p[1] + dirs[k + 1];
+ if (vis.remove(x * n + y)) {
q.offer(new int[] {x, y});
}
}
@@ -202,24 +205,92 @@ class Solution {
return -1;
}
- private void dfs(int i, int j, GridMaster master) {
+ private void dfs(int i, int j) {
if (master.isTarget()) {
target = new int[] {i, j};
+ return;
}
for (int k = 0; k < 4; ++k) {
- char d = dir[k], nd = ndir[k];
int x = i + dirs[k], y = j + dirs[k + 1];
- if (master.canMove(d) && !s.contains(x * N + y)) {
- s.add(x * N + y);
- master.move(d);
- dfs(x, y, master);
- master.move(nd);
+ if (master.canMove(s.charAt(k)) && vis.add(x * n + y)) {
+ master.move(s.charAt(k));
+ dfs(x, y);
+ master.move(s.charAt((k + 2) % 4));
}
}
}
}
```
+### **C++**
+
+```cpp
+/**
+ * // This is the GridMaster's API interface.
+ * // You should not implement it, or speculate about its implementation
+ * class GridMaster {
+ * public:
+ * bool canMove(char direction);
+ * void move(char direction);
+ * boolean isTarget();
+ * };
+ */
+
+class Solution {
+private:
+ const int n = 2010;
+ int dirs[5] = {-1, 0, 1, 0, -1};
+ string s = "URDL";
+ int target;
+ unordered_set vis;
+
+public:
+ int findShortestPath(GridMaster& master) {
+ target = n * n;
+ vis.insert(0);
+ dfs(0, 0, master);
+ if (target == n * n) {
+ return -1;
+ }
+ vis.erase(0);
+ queue> q;
+ q.emplace(0, 0);
+ for (int ans = 0; q.size(); ++ans) {
+ for (int m = q.size(); m; --m) {
+ auto [i, j] = q.front();
+ q.pop();
+ if (i * n + j == target) {
+ return ans;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (vis.count(x * n + y)) {
+ vis.erase(x * n + y);
+ q.emplace(x, y);
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ void dfs(int i, int j, GridMaster& master) {
+ if (master.isTarget()) {
+ target = i * n + j;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (master.canMove(s[k]) && !vis.count(x * n + y)) {
+ vis.insert(x * n + y);
+ master.move(s[k]);
+ dfs(x, y, master);
+ master.move(s[(k + 2) % 4]);
+ }
+ }
+ }
+};
+```
+
### **...**
```
diff --git a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.cpp b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.cpp
new file mode 100644
index 0000000000000..ea414076852a2
--- /dev/null
+++ b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.cpp
@@ -0,0 +1,64 @@
+/**
+ * // This is the GridMaster's API interface.
+ * // You should not implement it, or speculate about its implementation
+ * class GridMaster {
+ * public:
+ * bool canMove(char direction);
+ * void move(char direction);
+ * boolean isTarget();
+ * };
+ */
+
+class Solution {
+private:
+ const int n = 2010;
+ int dirs[5] = {-1, 0, 1, 0, -1};
+ string s = "URDL";
+ int target;
+ unordered_set vis;
+
+public:
+ int findShortestPath(GridMaster& master) {
+ target = n * n;
+ vis.insert(0);
+ dfs(0, 0, master);
+ if (target == n * n) {
+ return -1;
+ }
+ vis.erase(0);
+ queue> q;
+ q.emplace(0, 0);
+ for (int ans = 0; q.size(); ++ans) {
+ for (int m = q.size(); m; --m) {
+ auto [i, j] = q.front();
+ q.pop();
+ if (i * n + j == target) {
+ return ans;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (vis.count(x * n + y)) {
+ vis.erase(x * n + y);
+ q.emplace(x, y);
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ void dfs(int i, int j, GridMaster& master) {
+ if (master.isTarget()) {
+ target = i * n + j;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (master.canMove(s[k]) && !vis.count(x * n + y)) {
+ vis.insert(x * n + y);
+ master.move(s[k]);
+ dfs(x, y, master);
+ master.move(s[(k + 2) % 4]);
+ }
+ }
+ }
+};
\ No newline at end of file
diff --git a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.java b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.java
index 5eb3b6be9df6c..9d2568d1e80d9 100644
--- a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.java
+++ b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.java
@@ -1,66 +1,59 @@
-/**
- * // This is the GridMaster's API interface.
- * // You should not implement it, or speculate about its implementation
- * class GridMaster {
- * boolean canMove(char direction);
- * void move(char direction);
- * boolean isTarget();
- * }
- */
-
-class Solution {
- private static final char[] dir = {'U', 'R', 'D', 'L'};
- private static final char[] ndir = {'D', 'L', 'U', 'R'};
- private static final int[] dirs = {-1, 0, 1, 0, -1};
- private static final int N = 1010;
- private Set s;
- private int[] target;
-
- public int findShortestPath(GridMaster master) {
- target = null;
- s = new HashSet<>();
- s.add(0);
- dfs(0, 0, master);
- if (target == null) {
- return -1;
- }
- s.remove(0);
- Deque q = new ArrayDeque<>();
- q.offer(new int[] {0, 0});
- int ans = -1;
- while (!q.isEmpty()) {
- ++ans;
- for (int n = q.size(); n > 0; --n) {
- int[] p = q.poll();
- int i = p[0], j = p[1];
- if (target[0] == i && target[1] == j) {
- return ans;
- }
- for (int k = 0; k < 4; ++k) {
- int x = i + dirs[k], y = j + dirs[k + 1];
- if (s.contains(x * N + y)) {
- s.remove(x * N + y);
- q.offer(new int[] {x, y});
- }
- }
- }
- }
- return -1;
- }
-
- private void dfs(int i, int j, GridMaster master) {
- if (master.isTarget()) {
- target = new int[] {i, j};
- }
- for (int k = 0; k < 4; ++k) {
- char d = dir[k], nd = ndir[k];
- int x = i + dirs[k], y = j + dirs[k + 1];
- if (master.canMove(d) && !s.contains(x * N + y)) {
- s.add(x * N + y);
- master.move(d);
- dfs(x, y, master);
- master.move(nd);
- }
- }
- }
+/**
+ * // This is the GridMaster's API interface.
+ * // You should not implement it, or speculate about its implementation
+ * class GridMaster {
+ * boolean canMove(char direction);
+ * void move(char direction);
+ * boolean isTarget();
+ * }
+ */
+
+class Solution {
+ private int[] target;
+ private GridMaster master;
+ private final int n = 2010;
+ private final String s = "URDL";
+ private final int[] dirs = {-1, 0, 1, 0, -1};
+ private final Set vis = new HashSet<>();
+
+ public int findShortestPath(GridMaster master) {
+ this.master = master;
+ dfs(0, 0);
+ if (target == null) {
+ return -1;
+ }
+ vis.remove(0);
+ Deque q = new ArrayDeque<>();
+ q.offer(new int[] {0, 0});
+ for (int ans = 0; !q.isEmpty(); ++ans) {
+ for (int m = q.size(); m > 0; --m) {
+ var p = q.poll();
+ if (p[0] == target[0] && p[1] == target[1]) {
+ return ans;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = p[0] + dirs[k], y = p[1] + dirs[k + 1];
+ if (vis.remove(x * n + y)) {
+ q.offer(new int[] {x, y});
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ private void dfs(int i, int j) {
+ if (master.isTarget()) {
+ target = new int[] {i, j};
+ return;
+ }
+ for (int k = 0; k < 4; ++k) {
+ int x = i + dirs[k], y = j + dirs[k + 1];
+ if (master.canMove(s.charAt(k)) && vis.add(x * n + y)) {
+ master.move(s.charAt(k));
+ dfs(x, y);
+ master.move(s.charAt((k + 2) % 4));
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.py b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.py
index e7e4b037bdb79..0b307b9aafbd7 100644
--- a/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.py
+++ b/solution/1700-1799/1778.Shortest Path in a Hidden Grid/Solution.py
@@ -1,56 +1,53 @@
-# """
-# This is GridMaster's API interface.
-# You should not implement it, or speculate about its implementation
-# """
-# class GridMaster(object):
-# def canMove(self, direction: str) -> bool:
-#
-#
-# def move(self, direction: str) -> bool:
-#
-#
-# def isTarget(self) -> None:
-#
-#
-
-
-class Solution(object):
- def findShortestPath(self, master: 'GridMaster') -> int:
- def dfs(i, j):
- nonlocal target
- if master.isTarget():
- target = (i, j)
- for dir, ndir, a, b in dirs:
- x, y = i + a, j + b
- if master.canMove(dir) and (x, y) not in s:
- s.add((x, y))
- master.move(dir)
- dfs(x, y)
- master.move(ndir)
-
- target = None
- s = set()
- dirs = [
- ['U', 'D', -1, 0],
- ['D', 'U', 1, 0],
- ['L', 'R', 0, -1],
- ['R', 'L', 0, 1],
- ]
- dfs(0, 0)
- if target is None:
- return -1
- s.remove((0, 0))
- q = deque([(0, 0)])
- ans = -1
- while q:
- ans += 1
- for _ in range(len(q)):
- i, j = q.popleft()
- if (i, j) == target:
- return ans
- for _, _, a, b in dirs:
- x, y = i + a, j + b
- if (x, y) in s:
- s.remove((x, y))
- q.append((x, y))
- return -1
+# """
+# This is GridMaster's API interface.
+# You should not implement it, or speculate about its implementation
+# """
+# class GridMaster(object):
+# def canMove(self, direction: str) -> bool:
+#
+#
+# def move(self, direction: str) -> bool:
+#
+#
+# def isTarget(self) -> None:
+#
+#
+
+
+class Solution(object):
+ def findShortestPath(self, master: "GridMaster") -> int:
+ def dfs(i: int, j: int):
+ if master.isTarget():
+ nonlocal target
+ target = (i, j)
+ return
+ for k, c in enumerate(s):
+ x, y = i + dirs[k], j + dirs[k + 1]
+ if master.canMove(c) and (x, y) not in vis:
+ vis.add((x, y))
+ master.move(c)
+ dfs(x, y)
+ master.move(s[(k + 2) % 4])
+
+ s = "URDL"
+ dirs = (-1, 0, 1, 0, -1)
+ target = None
+ vis = set()
+ dfs(0, 0)
+ if target is None:
+ return -1
+ vis.discard((0, 0))
+ q = deque([(0, 0)])
+ ans = -1
+ while q:
+ ans += 1
+ for _ in range(len(q)):
+ i, j = q.popleft()
+ if (i, j) == target:
+ return ans
+ for a, b in pairwise(dirs):
+ x, y = i + a, j + b
+ if (x, y) in vis:
+ vis.remove((x, y))
+ q.append((x, y))
+ return -1