Given an array arr[] of N positive integers and two positive integers S and K, the task is to reach the position of the array whose value is K from index S. We can only move from current index i to index (i + arr[i]) or (i – arr[i]). If there is a way to reach the position of the array whose value is K then print “Yes” else print “No”.
Examples:
Input: arr[] = {4, 2, 3, 0, 3, 1, 2}, S = 5, K = 0.
Output: Yes
Explanation:
Initially we are standing at index 5 that is element 1 hence we can move one step forward or backward. Therefore, all possible ways to reach at index 3 with value 0 are:
index 5 -> index 4 -> index 1 -> index 3
index 5 -> index 6 -> index 4 -> index 1 -> index 3. Since it is possible to reach index 3 our output is yes.
Input: arr[] = {0, 3, 2, 1, 2}, S = 2, K = 3
Output: No
Explanation:
There is no way to reach index 1 with value 3.
Method 1 – Using BFS The Breadth-first search(BFS) approach is discussed below:
- Consider start index S as the source node and insert it into the queue.
- While the queue is not empty do the following:
- Pop the element from the top of the queue say temp.
- If temp is already visited or it is array out of bound index then, go to step 1.
- Else mark it as visited.
- Now if temp is the index of the array whose value is K, then print “Yes”.
- Else take two possible destinations from temp to (temp + arr[temp]), (temp – arr[temp]) and push it into the queue.
- If the index with value K is not reached after the above steps then print “No”.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool check( int arr[], int & s_start,
int start, bool visited[],
int size, int K)
{
queue< int > q;
q.push(start);
while (!q.empty()) {
int front = q.front();
q.pop();
visited[front] = true ;
if (arr[front] == K
&& front != s_start) {
return true ;
}
if (front + arr[front] >= 0
&& front + arr[front] < size
&& visited[front + arr[front]]
== false ) {
q.push(front + arr[front]);
}
if (front - arr[front] >= 0
&& front - arr[front] < size
&& visited[front - arr[front]]
== false ) {
q.push(front - arr[front]);
}
}
return false ;
}
void solve( int arr[], int n, int start,
int K)
{
bool visited[n] = { false };
bool ans = check(arr, start, start,
visited, n, K);
if (ans)
cout << "Yes" ;
else
cout << "No" ;
}
int main()
{
int arr[] = { 3, 0, 2, 1, 2 };
int start = 2;
int K = 0;
int N = sizeof (arr) / sizeof (arr[0]);
solve(arr, N, start, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean check( int arr[], int s_start, int start,
boolean visited[], int size, int K)
{
Queue<Integer> q = new LinkedList<Integer>();
q.add(start);
while (!q.isEmpty())
{
int front = q.peek();
q.remove();
visited[front] = true ;
if (arr[front] == K && front != s_start)
{
return true ;
}
if (front + arr[front] >= 0 &&
front + arr[front] < size &&
visited[front + arr[front]] == false )
{
q.add(front + arr[front]);
}
if (front - arr[front] >= 0 &&
front - arr[front] < size &&
visited[front - arr[front]] == false )
{
q.add(front - arr[front]);
}
}
return false ;
}
static void solve( int arr[], int n, int start, int K)
{
boolean visited[] = new boolean [n];
boolean ans = check(arr, start, start,
visited, n, K);
if (ans)
System.out.print( "Yes" );
else
System.out.print( "No" );
}
public static void main(String[] args)
{
int arr[] = { 3 , 0 , 2 , 1 , 2 };
int start = 2 ;
int K = 0 ;
int N = arr.length;
solve(arr, N, start, K);
}
}
|
Python3
def check(arr, s_start, start,
visited, size, K):
q = []
q.append(start)
while ( len (q) ! = 0 ):
front = q[ - 1 ]
q.pop( 0 )
visited[front] = True
if (arr[front] = = K and front ! = s_start):
return True
if (front + arr[front] > = 0 and
front + arr[front] < size and
visited[front + arr[front]] = = False ):
q.append(front + arr[front])
if (front - arr[front] > = 0 and
front - arr[front] < size and
visited[front - arr[front]] = = False ):
q.append(front - arr[front])
return False
def solve(arr, n, start, K):
visited = [ False for i in range (n)]
ans = check(arr, start, start,
visited, n, K)
if (ans):
print ( 'Yes' )
else :
print ( 'No' )
if __name__ = = "__main__" :
arr = [ 3 , 0 , 2 , 1 , 2 ]
start = 2
K = 0
N = len (arr)
solve(arr, N, start, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool check( int []arr, int s_start, int start,
bool []visited, int size, int K)
{
Queue< int > q = new Queue< int >();
q.Enqueue(start);
while (q.Count != 0)
{
int front = q.Peek();
q.Dequeue();
visited[front] = true ;
if (arr[front] == K && front != s_start)
{
return true ;
}
if (front + arr[front] >= 0 &&
front + arr[front] < size &&
visited[front + arr[front]] == false )
{
q.Enqueue(front + arr[front]);
}
if (front - arr[front] >= 0 &&
front - arr[front] < size &&
visited[front - arr[front]] == false )
{
q.Enqueue(front - arr[front]);
}
}
return false ;
}
static void solve( int []arr, int n, int start,
int K)
{
bool []visited = new bool [n];
bool ans = check(arr, start, start,
visited, n, K);
if (ans)
Console.Write( "Yes" );
else
Console.Write( "No" );
}
public static void Main(String[] args)
{
int []arr = { 3, 0, 2, 1, 2 };
int start = 2;
int K = 0;
int N = arr.Length;
solve(arr, N, start, K);
}
}
|
Javascript
<script>
function check(arr, s_start, start, visited, size, K)
{
let q = [];
q.push(start);
while (q.length > 0)
{
let front = q[0];
q.shift();
visited[front] = true ;
if (arr[front] == K && front != s_start)
{
return true ;
}
if (front + arr[front] >= 0 &&
front + arr[front] < size &&
visited[front + arr[front]] == false )
{
q.push(front + arr[front]);
}
if (front - arr[front] >= 0 &&
front - arr[front] < size &&
visited[front - arr[front]] == false )
{
q.push(front - arr[front]);
}
}
return false ;
}
function solve(arr, n, start, K)
{
let visited = new Array(n);
let ans = check(arr, start, start,
visited, n, K);
if (ans)
document.write( "Yes" );
else
document.write( "No" );
}
let arr = [ 3, 0, 2, 1, 2 ];
let start = 2;
let K = 0;
let N = arr.length;
solve(arr, N, start, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Method 2 – Using DFS: The Depth-first search(DFS) approach is discussed below:
- Initialize an array visited[] to mark visited vertex as true.
- Start with the start index S and explore other index depth-wise using recursion.
- In each recursive call, we check if that index is valid or previously not visited. If not so, we return false.
- Else if that index value is K, we return true.
- Else mark that index as visited and process recursively for i + arr[i] and i – arr[i] from current index i.
- If any of the recursive calls return true, this means that we reach to index with value K is possible and we print “Yes” Else print “No”.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool check( int arr[], int & s_start,
int start, bool visited[],
int size, int K)
{
if (start < 0 || start >= size
|| visited[start]) {
return false ;
}
if (arr[start] == K
&& start != s_start) {
return true ;
}
visited[start] = true ;
return (check(arr, s_start,
start + arr[start],
visited, size, K)
|| check(arr, s_start,
start - arr[start],
visited, size, K));
}
void solve( int arr[], int n, int start,
int K)
{
bool visited[n] = { false };
bool ans = check(arr, start, start,
visited, n, K);
if (ans)
cout << "Yes" ;
else
cout << "No" ;
}
int main()
{
int arr[] = { 3, 0, 2, 1, 2 };
int start = 2;
int K = 0;
int N = sizeof (arr) / sizeof (arr[0]);
solve(arr, N, start, K);
return 0;
}
|
Java
import java.util.Arrays;
class GFG{
public static boolean check( int [] arr, int s_start,
int start, boolean [] visited,
int size, int K)
{
if (start < 0 || start >= size ||
visited[start])
{
return false ;
}
if (arr[start] == K &&
start != s_start)
{
return true ;
}
visited[start] = true ;
return (check(arr, s_start,
start + arr[start],
visited, size, K) ||
check(arr, s_start,
start - arr[start],
visited, size, K));
}
public static void solve( int [] arr, int n,
int start, int K)
{
boolean [] visited = new boolean [n];
Arrays.fill(visited, false );
boolean ans = check(arr, start, start,
visited, n, K);
if (ans)
System.out.print( "Yes" );
else
System.out.print( "No" );
}
public static void main(String[] args)
{
int arr[] = { 3 , 0 , 2 , 1 , 2 };
int start = 2 ;
int K = 0 ;
int N = arr.length;
solve(arr, N, start, K);
}
}
|
Python3
def check(arr, s_start, start, visited,
size, K):
if (start < 0 or start > = size or
visited[start]):
return False
if (arr[start] = = K and
start ! = s_start):
return True
visited[start] = True
return (check(arr, s_start,
start + arr[start],
visited, size, K) or
check(arr, s_start,
start - arr[start],
visited, size, K))
def solve(arr, n, start, K):
visited = [ False ] * n
ans = check(arr, start, start,
visited, n, K)
if (ans):
print ( "Yes" )
else :
print ( "No" )
if __name__ = = "__main__" :
arr = [ 3 , 0 , 2 , 1 , 2 ]
start = 2
K = 0
N = len (arr)
solve(arr, N, start, K)
|
C#
using System;
class GFG{
public static bool check( int [] arr, int s_start,
int start, bool [] visited,
int size, int K)
{
if (start < 0 || start >= size||
visited[start])
{
return false ;
}
if (arr[start] == K &&
start != s_start)
{
return true ;
}
visited[start] = true ;
return (check(arr, s_start,
start + arr[start],
visited, size, K) ||
check(arr, s_start,
start - arr[start],
visited, size, K));
}
public static void solve( int [] arr, int n,
int start, int K)
{
bool [] visited = new bool [n];
bool ans = check(arr, start, start,
visited, n, K);
if (ans)
Console.Write( "Yes" );
else
Console.Write( "No" );
}
public static void Main(String[] args)
{
int []arr = { 3, 0, 2, 1, 2 };
int start = 2;
int K = 0;
int N = arr.Length;
solve(arr, N, start, K);
}
}
|
Javascript
<script>
function check(arr, s_start,
start, visited,
size, K)
{
if (start < 0 || start >= size
|| visited[start]) {
return false ;
}
if (arr[start] == K
&& start != s_start) {
return true ;
}
visited[start] = true ;
return (check(arr, s_start,
start + arr[start],
visited, size, K)
|| check(arr, s_start,
start - arr[start],
visited, size, K));
}
function solve(arr, n, start, K)
{
var visited = Array(n).fill( false );
var ans = check(arr, start, start,
visited, n, K);
if (ans)
document.write( "Yes" );
else
document.write( "No" );
}
var arr = [ 3, 0, 2, 1, 2 ];
var start = 2;
var K = 0;
var N = arr.length;
solve(arr, N, start, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Method 3 : DFS (Efficient Method) : We will follow the steps mention below :
- As array contains only positive number, so each time using dfs multiply that number with -1 which confirms that we have visited that element before.
- Check if the given index element is same as K or not.
- Otherwise, call dfs by increasing start + arr[start] and by decreasing start – arr[start].
- In base case check if start is in range of array length and also check is it visited before or not.
Implementation of above approach :
C++
#include <bits/stdc++.h>
using namespace std;
bool dfs( int arr[], int N, int start, int K)
{
if (start < 0 || start >= N || arr[start] < 0)
return false ;
arr[start] *= -1;
return ( abs (arr[start]) == K)
|| dfs(arr, N, start + arr[start], K)
|| dfs(arr, N, start - arr[start], K);
}
int main()
{
int arr[] = { 3, 0, 2, 1, 2 };
int start = 2;
int K = 0;
int N = sizeof (arr) / sizeof (arr[0]);
bool flag = dfs(arr, N, start, K);
if (flag)
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
public static boolean dfs( int [] arr, int N, int start,
int K)
{
if (start < 0 || start >= N || arr[start] < 0 )
return false ;
arr[start] *= - 1 ;
return (Math.abs(arr[start]) == K)
|| dfs(arr, N, start + arr[start], K)
|| dfs(arr, N, start - arr[start], K);
}
public static void main(String[] args)
{
int arr[] = { 3 , 0 , 2 , 1 , 2 };
int start = 2 ;
int K = 0 ;
int N = arr.length;
if (dfs(arr, N, start, K))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
def dfs(arr, N, start, K):
if start < 0 or start > = N or arr[start] < 0 :
return False
arr[start] * = - 1
return abs (arr[start]) = = K or dfs(arr, N, start + arr[start], K) or dfs(arr, N, start - arr[start], K)
arr = [ 3 , 0 , 2 , 1 , 2 ]
start = 2
K = 0
N = len (arr)
if dfs(arr, N, start, K):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections.Generic;
class GFG {
static bool dfs( int [] arr, int N, int start, int K)
{
if (start < 0 || start >= N || arr[start] < 0)
return false ;
arr[start] *= -1;
return (Math.Abs(arr[start]) == K)
|| dfs(arr, N, start + arr[start], K)
|| dfs(arr, N, start - arr[start], K);
}
static void Main()
{
int [] arr = { 3, 0, 2, 1, 2 };
int start = 2;
int K = 0;
int N = arr.Length;
if (dfs(arr, N, start, K))
Console.Write( "Yes" );
else
Console.Write( "No" );
}
}
|
Javascript
<script>
function dfs(arr, N, start, K)
{
if (start < 0 || start >= N || arr[start] < 0)
return false ;
arr[start] *= -1;
return (Math.abs(arr[start]) == K)
|| dfs(arr, N, start + arr[start], K)
|| dfs(arr, N, start - arr[start], K);
}
let arr = [ 3, 0, 2, 1, 2 ];
let start = 2;
let K = 0;
let N = arr.length;
if (dfs(arr, N, start, K))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Time Complexity : O(n)
Auxiliary Space : O(n), (Space is only used for recursion)