LeetCode — 跳跃游戏 III
问题陈述
给定一个非负整数数组 arr ,您最初位于 开始 数组的索引。当你在索引 一世 , 你可以跳到 i + arr[i] 或者 i — arr[i] , 检查是否可以到达 任何 值为 0 的索引。
请注意,您不能随时跳出数组。
问题陈述取自: https://leetcode.com/problems/jump-game-iii/
示例 1:
输入:arr = [4, 2, 3, 0, 3, 1, 2], start = 5
输出:真
解释:
到达索引 3 且值为 0 的所有可能方法是:
索引 5 -> 索引 4 -> 索引 1 -> 索引 3
索引 5 -> 索引 6 -> 索引 4 -> 索引 1 -> 索引 3
示例 2:
输入:arr = [4, 2, 3, 0, 3, 1, 2], start = 0
输出:真
解释:
到达索引 3 且值为 0 的一种可能方法是:
索引 0 -> 索引 4 -> 索引 1 -> 索引 3
示例 3:
输入:arr = [3, 0, 2, 1, 2], start = 2
输出:假
解释:没有办法到达值为 0 的索引 1。
约束:
- 1 <= arr.length <= 5 * 10^4
- 0 <= arr[i] < arr.length
- 0 <= 开始 < arr.length
解释
问题是扩展版 跳跃游戏 和 跳跃游戏二 .我们可以使用 BFS 或 DFS 方法来解决这个问题。
在这篇文章中,我们将探索 BFS 方式。
BFS方式
我们会将起始位置推入队列并开始探索其邻居。我们需要维护一个布尔数组来标记我们访问过的节点。
我们先检查一下算法:
// canReach(arr, start) - 设置 n = arr.size()
队列 q = [开始]
整数访问[n]
整数节点 - 循环 while !q.empty()
节点 = q.start()
q.pop() 如果 arr[节点] == 0
返回真 如果访问[节点]
继续 如果节点 - arr[节点] >= 0
q.push(节点 - arr[节点]) 如果节点 + arr[节点] < 4
q.push(节点 + arr[节点]) 访问[节点] = true
- 虽然结束 - 返回假
上述方法的时间复杂度为 上) ,空间复杂度为 上) .
让我们检查一下我们的解决方案 C++ , 戈朗 , 和 Javascript .
C++ 解决方案
类解决方案{
上市:
bool canReach(向量<int>& arr, int start) {
int n = arr.size();
队列<int>q{{开始}};
整数节点;
向量<bool>访问过(n); 而(!q.empty()){
节点 = q.front();
q.pop(); 如果(arr [节点] == 0){
返回真;
} 如果(访问[节点]){
继续;
} 如果(节点 - arr [节点] >= 0){
q.push(节点 - arr[节点]);
} 如果(节点 + arr [节点] < n){
q.push(节点 + arr[节点]);
} 访问[节点] = true;
} 返回假;
}
};
Golang 解决方案
func canReach(arr []int, start int) bool {
n := 长度 (arr)
队列:= []int{开始}
访问过 := make([]bool, n) 对于 len(队列)!= 0 {
节点:=队列[0]
尾=尾[1:] 如果 arr[节点] == 0 {
返回真
} 如果访问[节点] {
继续
} 如果节点 - arr[节点] >= 0 {
队列 = 追加(队列,节点 - arr [节点])
} 如果节点 + arr[节点] < n {
队列 = 追加(队列,节点 + arr[节点])
} 访问[节点] = true
} 返回假
}
Javascript 解决方案
var canReach = 函数(arr,开始){
让 n = arr.length;
让队列 = [开始];
让访问= [];
让节点; 而(队列长度> 0){
节点=队列[0];
queue.shift(); 如果(arr [节点] == 0){
返回真;
} 如果(访问[节点]){
继续;
} 如果(节点 - arr [节点] >= 0){
queue.push(node - arr[node]);
} 如果(节点 + arr [节点] < n){
queue.push(node + arr[node]);
} 访问[节点] = true;
} 返回假;
};
让我们针对给定的输入试运行我们的算法。
输入:arr = [4, 2, 3, 0, 3, 1, 2]
开始 = 5 第 1 步:n = arr.size()
= 7 队列<int>q{{开始}}
q = [5] 整数节点
向量<bool>访问过(n) 第 2 步:循环 while !q.empty()
q = [5]
真的 节点 = q.front()
= 5 q.pop()
q = [] 如果 arr[节点] == 0
arr[5] == 0
1 == 0
错误的 如果访问[节点]
访问过[5]
错误的 如果节点 - arr[节点] >= 0
5 - arr[5] >= 0
5 - 1 >= 0
4 >= 0
真的 q.push(节点 - arr[节点])
q.push(4) q = [4] 如果节点 + arr[节点] < n
5 + arr[5] < 7
5 + 1 < 7
6 < 7
真的 q.push(节点 + arr[节点])
q.push(6) q = [4, 6] 访问[节点] = true
已访问 [5] = 真 第 3 步:循环 while !q.empty()
q = [4, 6]
真的 节点 = q.front()
= 4 q.pop()
q = [6] 如果 arr[节点] == 0
arr[4] == 0
3 == 0
错误的 如果访问[节点]
访问[4]
错误的 如果节点 - arr[节点] >= 0
4 - arr[4] >= 0
4 - 3 >= 0
1 >= 0
真的 q.push(节点 - arr[节点])
q.push(1) q = [6, 1] 如果节点 + arr[节点] < n
4 + arr[4] < 7
4 + 3 < 7
7 < 7
错误的 访问[节点] = true
已访问 [4] = 真 第 4 步:循环 while !q.empty()
q = [6, 1]
真的 节点 = q.front()
= 6 q.pop()
q = [1] 如果 arr[节点] == 0
arr[6] == 0
2 == 0
错误的 如果访问[节点]
访问过[6]
错误的 如果节点 - arr[节点] >= 0
6 - arr[6] >= 0
6 - 2 >= 0
4 >= 0
真的 q.push(节点 - arr[节点])
q.push(4) q = [1, 4] 如果节点 + arr[节点] < n
6 + arr[6] < 7
6 + 2 < 7
8 < 7
错误的 访问[节点] = true
已访问 [6] = 真 第 5 步:循环 while !q.empty()
q = [1, 4]
真的 节点 = q.front()
= 1 q.pop()
q = [4] 如果 arr[节点] == 0
arr[1] == 0
2 == 0
错误的 如果访问[节点]
访问过[1]
错误的 如果节点 - arr[节点] >= 0
1 - arr[1] >= 0
1 - 2 >= 0
-1 >= 0
错误的 如果节点 + arr[节点] < n
1 + arr[1] < 7
1 + 2 < 7
3 < 7
真的 q.push(节点 + arr[节点])
q.push(3) q = [4, 3] 访问[节点] = true
已访问 [1] = 真 第 6 步:循环 while !q.empty()
q = [4, 3]
真的 节点 = q.front()
= 4 q.pop()
q = [3] 如果 arr[节点] == 0
arr[4] == 0
0 == 0
真的 返回真 我们将答案返回为真。
最初发表于 https://alkeshghorpade.me .
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
本文链接:https://www.qanswer.top/37980/51001911
标签:arr,索引,队列,节点,访问,push,跳跃,III,LeetCode From: https://www.cnblogs.com/amboke/p/16707271.html