这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。
请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。
注意,不管是什么情况下,你都无法跳到数组之外。
示例 1:
输入:arr = [4,2,3,0,3,1,2], start = 5 输出:true 解释: 到达值为 0 的下标 3 有以下可能方案:
下标 5 -> 下标 4 -> 下标 1 -> 下标 3 下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3
示例 2:
输入:arr = [4,2,3,0,3,1,2], start = 0 输出:true 解释: 到达值为 0 的下标 3 有以下可能方案:
下标 0 -> 下标 4 -> 下标 1 -> 下标 3
示例 3:
输入:arr = [3,0,2,1,2], start = 2 输出:false 解释:无法到达值为 0 的下标 1 处。
提示:
1 <= arr.length <= 5 * 10^4 0 <= arr[i] < arr.length 0 <= start <
arr.length
方法一 :dfs (递归)
class Solution {
public boolean canReach(int[] arr, int start) {
return dfs(arr, start, 0);
}
public boolean dfs(int[] arr, int start, int steps){
if(start < 0 || start >= arr.length) return false; //跳出界了,且之前都没有跳到为零的地方
if(steps > arr.length) return false; // 跳了数组长度次,还没有跳出0,(如果跳的所有次数有重复的话,接下来将会是无限循环,如果没有重复的话,就是把那些都跳过了,没有为0的数)
if(arr[start] == 0) return true; //如果跳到了0返回true
return dfs(arr, arr[start] + start, steps + 1) || dfs(arr, start - arr[start], steps + 1); //一直向下跳
}
}
class Solution {//深度优先搜索
public boolean canReach(int[] arr, int start) {
boolean[] dp=new boolean[arr.length]; //初始化为false
return dfs(arr,dp,start);
}
public boolean dfs(int[] arr,boolean[] dp,int start){
if(start<0||start>=arr.length)return false; //出界了遍历不到
if(arr[start]==0)return true; //遍历到0了
if(dp[start]){ //start的角标不为false 说明该位置之前被遍历过,没有遍历到0,没有必要再次遍历这个start了
return false;
}else{ //没有遍历该数
dp[start]=true;
}
return dfs(arr,dp,start+arr[start])||dfs(arr,dp,start-arr[start]); //深度遍历
}
}
方法二:bfs 广度优先遍历
用一个数组储存某下标是否被遍历过
class Solution {//广度优先搜索
public boolean canReach(int[] arr, int start) {
int len=arr.length;
boolean[] dp=new boolean[len]; //初始化为false
Queue<Integer> queue=new LinkedList<>();
queue.add(start);
while(!queue.isEmpty()){
int x=queue.poll(); //1. poll 移除并返问队列头部的元素 如果队列为空,则返回null
if(x+arr[x]<len&&!dp[x+arr[x]]){ //没被遍历过且没越界
dp[x+arr[x]]=true;
queue.add(x+arr[x]);
if(arr[x+arr[x]]==0)return true; //如果可以跳出循环
}
if(x-arr[x]>=0&&!dp[x-arr[x]]){ //没被遍历且美国姐
dp[x-arr[x]]=true;
queue.add(x-arr[x]);
if(arr[x-arr[x]]==0)return true; //跳出循环
}
}
return false; //遍历后都没有了
}
}