描述
这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。
请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。
注意,不管是什么情况下,你都无法跳到数组之外。
分析
关键的一点是对已经遍历过的点要标记,防止重复遍历陷入死循环。
DFS
- 从start开始遍历,若等于0,返回true,否则向两边跳跃。
- 跳跃的点要在数组范围内,并且不能已经被访问过,否则返回false。
- 若当前点可以遍历,标记已经被访问,然后向左右两边跳跃。
class Solution {
public boolean canReach(int[] arr, int start) {
if(start < 0 || start >= arr.length || arr[start] == -1){
return false;
}
if(arr[start] == 0){
return true;
}
int tmp = arr[start];
arr[start] = -1;
return canReach(arr,tmp+start) || canReach(arr,start - tmp);
}
}
BFS
把处在数组范围内的并且没有被访问的点加入队列;
弹出队列的元素判断是否为0,标记已经被遍历过。
class Solution {
public boolean canReach(int[] arr, int start) {
Queue<Integer> que = new LinkedList<>();
que.offer(start);
while(!que.isEmpty()){
int cur = que.poll();
int tmp = arr[cur];
if(tmp == 0){
return true;
}
arr[cur] = -1;
int lcur = cur - tmp;
int rcur = cur + tmp;
if(lcur >= 0 && arr[lcur] != -1){
que.offer(lcur);
}
if(rcur < arr.length && arr[rcur] != -1){
que.offer(rcur);
}
}
return false;
}
}