Given an array of non-negative integers arr, you are initially positioned at start&nbsp;index of the array. When you are at index i, you can jump&nbsp;to i + arr[i] or i - arr[i], check if you can reach to any index with value 0.

Notice that you can not jump outside of the array at any time.

&nbsp;
Example 1:

Input: arr = [4,2,3,0,3,1,2], start = 5
Output: true
Explanation: 
All possible ways to reach at index 3 with value 0 are: 
index 5 -&gt; index 4 -&gt; index 1 -&gt; index 3 
index 5 -&gt; index 6 -&gt; index 4 -&gt; index 1 -&gt; index 3 


Example 2:

Input: arr = [4,2,3,0,3,1,2], start = 0
Output: true 
Explanation: 
One possible way to reach at index 3 with value 0 is: 
index 0 -&gt; index 4 -&gt; index 1 -&gt; index 3


Example 3:

Input: arr = [3,0,2,1,2], start = 2
Output: false
Explanation: There is no way to reach at index 1 with value 0.


&nbsp;
Constraints:


	1 &lt;= arr.length &lt;= 5 * 104
	0 &lt;= arr[i] &lt;&nbsp;arr.length
	0 &lt;= start &lt; arr.length


class Solution:
    def canReach(self, arr: List[int], start: int) -> bool:
        vis = [0]*len(arr)
        q = deque() 
        q.append(start) 
        while q:
            cur = q.popleft() 
            print(cur)
            vis[cur] = 1
            if arr[cur] == 0:
                return True
            if cur+arr[cur]<len(arr) and vis[cur+arr[cur]] == 0:
                q.append(cur+arr[cur]) 
            if cur-arr[cur]>=0 and vis[cur-arr[cur]] == 0: 
                q.append(cur-arr[cur])  
        return False

            
class Solution {
    public boolean canReach(int[] arr, int start) {
        int n = arr.length;
        boolean[] vis = new boolean[n];
        Queue<Integer> q = new LinkedList<>();
        q.add(start);
        while(!q.isEmpty()){
            int size = q.size();
            while(size-- > 0){
                int curr = q.poll();
                if(vis[curr])
                    continue;
                if(arr[curr] == 0)
                    return true;
                if(curr+arr[curr] < n)
                    q.add(curr+arr[curr]);
                if(curr-arr[curr] >= 0)
                    q.add(curr-arr[curr]);
                vis[curr] = true;
            }
        }
        return false;
    }
}
class Solution {
public:
    bool dfs(int curr, vector<int>& arr, vector<bool>& visited, int size) {
		// edge cases - we can't go outside the array size and if the curr index is alredy visited it will repeat same recursion all over again so we can return false in that case too.
        if(curr < 0 || curr >= size || visited[curr])
            return false;
		// If we reach zero we can return true
        if(arr[curr] == 0)
            return true;
        visited[curr] = true;
		// do dfs in left and right and return two if any of the two paths end up reaching to zero
        return dfs(curr - arr[curr], arr, visited, size) || 
            dfs(curr + arr[curr], arr, visited, size);
    }
    
    bool canReach(vector<int>& arr, int start) {
        int size = arr.size();
        vector<bool> visited(size, false);
        return dfs(start, arr, visited, size);
    }
};
/**
 * @param {number[]} arr
 * @param {number} start
 * @return {boolean}
 */
var canReach = function(arr, start) {
        let queue = [start];
        while(queue.length) {
            let index = queue.shift();
            if(index >= 0 && index < arr.length && arr[index] >=0 ){
                if(arr[index] === 0)return true;
                let move = arr[index]
                arr[index] = -1   
                queue.push(index +move , index-move)
            }
        }
    return false;
};
Jump Game III