Skip to content

Commit 63ef033

Browse files
committed
feat: add solutions to lc problem: No.1654
No.1654.Minimum Jumps to Reach Home
1 parent 1ddd687 commit 63ef033

File tree

6 files changed

+172
-180
lines changed

6 files changed

+172
-180
lines changed

solution/1600-1699/1654.Minimum Jumps to Reach Home/README.md

Lines changed: 70 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@
6464

6565
**方法一:BFS**
6666

67+
我们可以将跳蚤的位置和跳跃方向作为状态,使用 BFS 搜索最短路径。本题比较关键的地方在于确定右边界,即跳蚤最远能跳到哪里。
68+
69+
如果 $a \geq b$,即往前跳的距离大于往后跳的距离,那么如果跳蚤在位置大于 $x+b$ 的地方,它就不能再往前跳了,因为跳蚤不能连续往后跳两次,如果继续往前跳,那么永远无法跳到 $x$ 的位置。因此,如果 $a \geq b$,那么右边界可以是 $x+b$。
70+
71+
如果 $a \lt b$,即往前跳的距离小于往后跳的距离,那么如果跳蚤所在的位置减去 $b$ 超过 $2000$,此时选择往后跳,否则往前跳。因此,如果 $a \lt b$,那么右边界不超过 $6000$。
72+
73+
综上,我们可以将右边界设置为 $6000$。
74+
75+
接下来,我们使用 BFS 搜索最短路径。我们使用一个队列,初始时将跳蚤的位置和跳跃方向作为状态加入队列。每次从队列中取出一个状态,如果该状态的位置等于 $x$,那么我们就找到了一条从初始状态到达目标状态的路径,返回当前的步数即可。否则,我们将当前状态的下一个状态加入队列,下一个状态有两种情况:
76+
77+
- 往前跳,跳跃方向为 $1$;
78+
- 当前跳跃方向为 $1$ 时,往后跳,跳跃方向为 $0$。
79+
80+
注意,我们需要判断下一个状态是否合法,即下一个状态的位置不超过右边界,且不在禁止的位置中,且未被访问过。
81+
82+
如果队列为空,说明无法到达目标位置,返回 $-1$。
83+
84+
时间复杂度 $O(M)$,空间复杂度 $O(M)$。其中 $M$ 是右边界,本题中 $M \leq 6000$。
85+
6786
<!-- tabs:start -->
6887

6988
### **Python3**
@@ -74,21 +93,21 @@
7493
class Solution:
7594
def minimumJumps(self, forbidden: List[int], a: int, b: int, x: int) -> int:
7695
s = set(forbidden)
77-
q = deque([(0, 0)])
78-
vis = {(0, 1), (0, -1)}
96+
q = deque([(0, 1)])
97+
vis = {(0, 1)}
7998
ans = 0
8099
while q:
81100
for _ in range(len(q)):
82-
i, dir = q.popleft()
101+
i, k = q.popleft()
83102
if i == x:
84103
return ans
85104
nxt = [(i + a, 1)]
86-
if dir != -1:
87-
nxt.append((i - b, -1))
88-
for j, dir in nxt:
89-
if 0 <= j <= 6000 and j not in s and (j, dir) not in vis:
90-
vis.add((j, dir))
91-
q.append((j, dir))
105+
if k & 1:
106+
nxt.append((i - b, 0))
107+
for j, k in nxt:
108+
if 0 <= j < 6000 and j not in s and (j, k) not in vis:
109+
q.append((j, k))
110+
vis.add((j, k))
92111
ans += 1
93112
return -1
94113
```
@@ -99,37 +118,35 @@ class Solution:
99118

100119
```java
101120
class Solution {
102-
private static final int N = 6010;
103-
104121
public int minimumJumps(int[] forbidden, int a, int b, int x) {
105122
Set<Integer> s = new HashSet<>();
106123
for (int v : forbidden) {
107124
s.add(v);
108125
}
109126
Deque<int[]> q = new ArrayDeque<>();
110-
q.offer(new int[] {0, 2});
111-
boolean[][] vis = new boolean[N][2];
112-
vis[0][0] = true;
127+
q.offer(new int[] {0, 1});
128+
final int n = 6000;
129+
boolean[][] vis = new boolean[n][2];
113130
vis[0][1] = true;
114131
int ans = 0;
115132
while (!q.isEmpty()) {
116133
for (int t = q.size(); t > 0; --t) {
117-
int[] p = q.poll();
118-
int i = p[0], dir = p[1];
134+
var p = q.poll();
135+
int i = p[0], k = p[1];
119136
if (i == x) {
120137
return ans;
121138
}
122139
List<int[]> nxt = new ArrayList<>();
123140
nxt.add(new int[] {i + a, 1});
124-
if (dir != 0) {
141+
if ((k & 1) == 1) {
125142
nxt.add(new int[] {i - b, 0});
126143
}
127-
for (int[] e : nxt) {
144+
for (var e : nxt) {
128145
int j = e[0];
129-
dir = e[1];
130-
if (j >= 0 && j < N && !s.contains(j) && !vis[j][dir]) {
131-
vis[j][dir] = true;
132-
q.offer(new int[] {j, dir});
146+
k = e[1];
147+
if (j >= 0 && j < n && !s.contains(j) && !vis[j][k]) {
148+
q.offer(new int[] {j, k});
149+
vis[j][k] = true;
133150
}
134151
}
135152
}
@@ -145,31 +162,30 @@ class Solution {
145162
```cpp
146163
class Solution {
147164
public:
148-
const int N = 6010;
149-
150165
int minimumJumps(vector<int>& forbidden, int a, int b, int x) {
151166
unordered_set<int> s(forbidden.begin(), forbidden.end());
152-
queue<vector<int>> q;
153-
q.push({0, 0});
154-
vector<vector<bool>> vis(N, vector<bool>(2));
155-
vis[0][0] = true;
167+
queue<pair<int, int>> q;
168+
q.emplace(0, 1);
169+
const int n = 6000;
170+
bool vis[n][2];
171+
memset(vis, false, sizeof(vis));
156172
vis[0][1] = true;
157173
int ans = 0;
158174
while (!q.empty()) {
159175
for (int t = q.size(); t; --t) {
160-
auto p = q.front();
176+
auto [i, k] = q.front();
161177
q.pop();
162-
int i = p[0], dir = p[1];
163-
if (i == x) return ans;
164-
vector<vector<int>> nxt;
165-
nxt.push_back({i + a, 1});
166-
if (dir) nxt.push_back({i - b, 0});
167-
for (auto& e : nxt) {
168-
int j = e[0];
169-
dir = e[1];
170-
if (j >= 0 && j < N && !s.count(j) && !vis[j][dir]) {
171-
vis[j][dir] = true;
172-
q.push({j, dir});
178+
if (i == x) {
179+
return ans;
180+
}
181+
vector<pair<int, int>> nxts = {{i + a, 1}};
182+
if (k & 1) {
183+
nxts.emplace_back(i - b, 0);
184+
}
185+
for (auto [j, l] : nxts) {
186+
if (j >= 0 && j < n && !s.count(j) && !vis[j][l]) {
187+
vis[j][l] = true;
188+
q.emplace(j, l);
173189
}
174190
}
175191
}
@@ -183,38 +199,32 @@ public:
183199
### **Go**
184200
185201
```go
186-
func minimumJumps(forbidden []int, a int, b int, x int) int {
187-
n := 6010
188-
s := make(map[int]bool)
202+
func minimumJumps(forbidden []int, a int, b int, x int) (ans int) {
203+
s := map[int]bool{}
189204
for _, v := range forbidden {
190205
s[v] = true
191206
}
192-
q := [][]int{[]int{0, 0}}
193-
vis := make([][]bool, n)
194-
for i := range vis {
195-
vis[i] = make([]bool, 2)
196-
}
197-
vis[0][0] = true
207+
q := [][2]int{[2]int{0, 1}}
208+
const n = 6000
209+
vis := make([][2]bool, n)
198210
vis[0][1] = true
199-
ans := 0
200211
for len(q) > 0 {
201212
for t := len(q); t > 0; t-- {
202213
p := q[0]
203214
q = q[1:]
204-
i, dir := p[0], p[1]
215+
i, k := p[0], p[1]
205216
if i == x {
206-
return ans
217+
return
207218
}
208-
nxt := [][]int{[]int{i + a, 1}}
209-
if dir != 0 {
210-
nxt = append(nxt, []int{i - b, 0})
219+
nxt := [][2]int{[2]int{i + a, 1}}
220+
if k&1 == 1 {
221+
nxt = append(nxt, [2]int{i - b, 0})
211222
}
212223
for _, e := range nxt {
213-
j := e[0]
214-
dir = e[1]
215-
if j >= 0 && j < n && !s[j] && !vis[j][dir] {
216-
vis[j][dir] = true
217-
q = append(q, []int{j, dir})
224+
j, l := e[0], e[1]
225+
if j >= 0 && j < n && !s[j] && !vis[j][l] {
226+
q = append(q, [2]int{j, l})
227+
vis[j][l] = true
218228
}
219229
}
220230
}

solution/1600-1699/1654.Minimum Jumps to Reach Home/README_EN.md

Lines changed: 51 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,21 @@ BFS.
6666
class Solution:
6767
def minimumJumps(self, forbidden: List[int], a: int, b: int, x: int) -> int:
6868
s = set(forbidden)
69-
q = deque([(0, 0)])
70-
vis = {(0, 1), (0, -1)}
69+
q = deque([(0, 1)])
70+
vis = {(0, 1)}
7171
ans = 0
7272
while q:
7373
for _ in range(len(q)):
74-
i, dir = q.popleft()
74+
i, k = q.popleft()
7575
if i == x:
7676
return ans
7777
nxt = [(i + a, 1)]
78-
if dir != -1:
79-
nxt.append((i - b, -1))
80-
for j, dir in nxt:
81-
if 0 <= j <= 6000 and j not in s and (j, dir) not in vis:
82-
vis.add((j, dir))
83-
q.append((j, dir))
78+
if k & 1:
79+
nxt.append((i - b, 0))
80+
for j, k in nxt:
81+
if 0 <= j < 6000 and j not in s and (j, k) not in vis:
82+
q.append((j, k))
83+
vis.add((j, k))
8484
ans += 1
8585
return -1
8686
```
@@ -89,37 +89,35 @@ class Solution:
8989

9090
```java
9191
class Solution {
92-
private static final int N = 6010;
93-
9492
public int minimumJumps(int[] forbidden, int a, int b, int x) {
9593
Set<Integer> s = new HashSet<>();
9694
for (int v : forbidden) {
9795
s.add(v);
9896
}
9997
Deque<int[]> q = new ArrayDeque<>();
100-
q.offer(new int[] {0, 2});
101-
boolean[][] vis = new boolean[N][2];
102-
vis[0][0] = true;
98+
q.offer(new int[] {0, 1});
99+
final int n = 6000;
100+
boolean[][] vis = new boolean[n][2];
103101
vis[0][1] = true;
104102
int ans = 0;
105103
while (!q.isEmpty()) {
106104
for (int t = q.size(); t > 0; --t) {
107-
int[] p = q.poll();
108-
int i = p[0], dir = p[1];
105+
var p = q.poll();
106+
int i = p[0], k = p[1];
109107
if (i == x) {
110108
return ans;
111109
}
112110
List<int[]> nxt = new ArrayList<>();
113111
nxt.add(new int[] {i + a, 1});
114-
if (dir != 0) {
112+
if ((k & 1) == 1) {
115113
nxt.add(new int[] {i - b, 0});
116114
}
117-
for (int[] e : nxt) {
115+
for (var e : nxt) {
118116
int j = e[0];
119-
dir = e[1];
120-
if (j >= 0 && j < N && !s.contains(j) && !vis[j][dir]) {
121-
vis[j][dir] = true;
122-
q.offer(new int[] {j, dir});
117+
k = e[1];
118+
if (j >= 0 && j < n && !s.contains(j) && !vis[j][k]) {
119+
q.offer(new int[] {j, k});
120+
vis[j][k] = true;
123121
}
124122
}
125123
}
@@ -135,31 +133,30 @@ class Solution {
135133
```cpp
136134
class Solution {
137135
public:
138-
const int N = 6010;
139-
140136
int minimumJumps(vector<int>& forbidden, int a, int b, int x) {
141137
unordered_set<int> s(forbidden.begin(), forbidden.end());
142-
queue<vector<int>> q;
143-
q.push({0, 0});
144-
vector<vector<bool>> vis(N, vector<bool>(2));
145-
vis[0][0] = true;
138+
queue<pair<int, int>> q;
139+
q.emplace(0, 1);
140+
const int n = 6000;
141+
bool vis[n][2];
142+
memset(vis, false, sizeof(vis));
146143
vis[0][1] = true;
147144
int ans = 0;
148145
while (!q.empty()) {
149146
for (int t = q.size(); t; --t) {
150-
auto p = q.front();
147+
auto [i, k] = q.front();
151148
q.pop();
152-
int i = p[0], dir = p[1];
153-
if (i == x) return ans;
154-
vector<vector<int>> nxt;
155-
nxt.push_back({i + a, 1});
156-
if (dir) nxt.push_back({i - b, 0});
157-
for (auto& e : nxt) {
158-
int j = e[0];
159-
dir = e[1];
160-
if (j >= 0 && j < N && !s.count(j) && !vis[j][dir]) {
161-
vis[j][dir] = true;
162-
q.push({j, dir});
149+
if (i == x) {
150+
return ans;
151+
}
152+
vector<pair<int, int>> nxts = {{i + a, 1}};
153+
if (k & 1) {
154+
nxts.emplace_back(i - b, 0);
155+
}
156+
for (auto [j, l] : nxts) {
157+
if (j >= 0 && j < n && !s.count(j) && !vis[j][l]) {
158+
vis[j][l] = true;
159+
q.emplace(j, l);
163160
}
164161
}
165162
}
@@ -173,38 +170,32 @@ public:
173170
### **Go**
174171
175172
```go
176-
func minimumJumps(forbidden []int, a int, b int, x int) int {
177-
n := 6010
178-
s := make(map[int]bool)
173+
func minimumJumps(forbidden []int, a int, b int, x int) (ans int) {
174+
s := map[int]bool{}
179175
for _, v := range forbidden {
180176
s[v] = true
181177
}
182-
q := [][]int{[]int{0, 0}}
183-
vis := make([][]bool, n)
184-
for i := range vis {
185-
vis[i] = make([]bool, 2)
186-
}
187-
vis[0][0] = true
178+
q := [][2]int{[2]int{0, 1}}
179+
const n = 6000
180+
vis := make([][2]bool, n)
188181
vis[0][1] = true
189-
ans := 0
190182
for len(q) > 0 {
191183
for t := len(q); t > 0; t-- {
192184
p := q[0]
193185
q = q[1:]
194-
i, dir := p[0], p[1]
186+
i, k := p[0], p[1]
195187
if i == x {
196-
return ans
188+
return
197189
}
198-
nxt := [][]int{[]int{i + a, 1}}
199-
if dir != 0 {
200-
nxt = append(nxt, []int{i - b, 0})
190+
nxt := [][2]int{[2]int{i + a, 1}}
191+
if k&1 == 1 {
192+
nxt = append(nxt, [2]int{i - b, 0})
201193
}
202194
for _, e := range nxt {
203-
j := e[0]
204-
dir = e[1]
205-
if j >= 0 && j < n && !s[j] && !vis[j][dir] {
206-
vis[j][dir] = true
207-
q = append(q, []int{j, dir})
195+
j, l := e[0], e[1]
196+
if j >= 0 && j < n && !s[j] && !vis[j][l] {
197+
q = append(q, [2]int{j, l})
198+
vis[j][l] = true
208199
}
209200
}
210201
}

0 commit comments

Comments
 (0)