跳跃数组 03

这里有一个非负整数数组 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;                  //遍历后都没有了
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值