Check if the End of the Array can be Reached from a given Position


In this problem, we will check whether we can reach the array’s end by moving back or ahead by nums[p] moves from the current position.

The naïve approach to solve the problem is to check all possibilities to move into the array and see if we can reach the array’s end.

Another approach is using the queue and BFS traversal in the array. In this tutorial, we will learn both approaches to check whether we can reach to the end of the array.

Problem statement − We have given a nums[] array containing the positive integers. Also, we have given the start value, representing the starting index of movement. We need to check whether we can reach to the end of the given array after performing multiple operations from the start index. In each operation, we can jump from the current index to curr_index −nums[curr_index] or curr_index + nums[curr_index].

Sample Examples

Input

nums[] = {5, 4, 3, 2, 1, 6}, start = 1

Output

Yes

Explanation− When we start from the 1st index, we can reach the end by making a jump of size 4 from m 1st index.

Input

nums[] = {5, 0, 3, 2, 1, 6}, start = 1

Output

No

Explanation − The start index contains 0. So, we can’t move from the 1st index.

Input

nums[] = {6, 5, 3, 2, 1, 4, 7}; start = 2;

Output

Yes

Explanation − We can follow the below steps.

  • From the 2nd index, we can reach to the (2 + 3) 5th index.

  • From the 5th index, we can move back and reach the (5 − 4), 1st index.

  • From the 1st index, we can move to the end of the array.

Approach 1

This approach uses the recursive function to solve the problem. We will check for all possible moves using the recursive function. If we can reach the end of the array in any move, we will print Yes. Otherwise, we will print No.

Algorithm

Step 1 − If the start index is less than 0 or greater than N, return false.

Step 2 − If the start index is equal to N − 1, return true.

Step 3 − If the element at the current index is 0, return false.

Step 4 − Make a recursive function call to move back or ahead from the current position.

Step 5 − Take OR of the returned value of both the recursive function call and return from the current function call.

Example

#include <bits/stdc++.h>
using namespace std;

bool reachToEnd(int nums[], int N, int start) {
    if (start < 0 || start > N) {
        return false;
    }
    // When we reach at the end
    if (start == N - 1) {
        return true;
    }
    // When we can't move from the current position
    if (nums[start] == 0) {
        return false;
    }
    return reachToEnd(nums, N, start - nums[start]) || reachToEnd(nums, N, start + nums[start]);
}
int main(){
    int nums[] = {5, 4, 3, 2, 1, 6};
    int start = 1;
    int N = sizeof(nums) / sizeof(nums[0]);
    bool res = reachToEnd(nums, N, start);
    if(res) {
        cout << "Yes, we can reach to the end node!";
    } else {
        cout << "No, we can't reach to the end node!";
    }
    return 0;
}

Output

Yes, we can reach to the end node!

Time complexity &minus O(2N) as we make two moves for each element.

Space complexity &minus O(1), as we don’t use any extra space.

Approach 2

In this approach, we will use the queue data structure and make a BFS traversal in the array. Also, we will use the vis[] array to keep track of the visited array elements. We will insert each possible movement from the current position to the queue and traverse in a BFS manner.

Algorithm

Step 1 − Define the ‘que’ name queue data structure. Also, define the vis[] array of size n and initialize with the ‘false’ boolean value. Also, initialize the ‘isEnd’ variable with false to track whether we reach to the end.

Step 2 − Insert the start index into the queue.

Step 3 − Make iterations using the while loop until the queue becomes empty.

Step 4 − Take the first element from the queue, and store it in the ‘temp’ variable. If vis[temp] is true, move to the next iteration. Otherwise, make vis[temp] true.

Step 5 − If the temp is equal to n−1, update ‘isEnd’ to true, and use the break keyword to break the loop.

Step 6 − If temp + nums[temp] is less than N, insert it into the queue.

Step 7 − If temp − nums[temp] is greater than or equal to −1, insert it into the queue.

Step 8 − Print the output based on the ‘isEnd’ value once the loop iteration completes.

Example

#include <bits/stdc++.h>
using namespace std;

void reachToEnd(int nums[], int n, int start) {
    queue<int> que;
    // Make all nodes as not visited
    bool vis[n] = {false};
    // To track whether we reached at the end
    bool isEnd = false;
    que.push(start);
    while (!que.empty()) {
        int temp = que.front();
        que.pop();
        // When the node is visited
        if (vis[temp] == true)
            continue;
        // Mark the current node as visited
        vis[temp] = true;
        // When we reach at the end
        if (temp == n - 1) {
            isEnd = true;
            break;
        }
        // Check the possibility to reach
        if (temp + nums[temp] < n) {
            que.push(temp + nums[temp]);
        }
        if (temp - nums[temp] >= 0) {
            que.push(temp - nums[temp]);
        }
    }
    if (isEnd == true) {
        cout <<"Yes, we can reach to the end node!";
    } else {
        cout << "No, we can't reach to the end node!";
    }
}
int main() {
    // Given array arr[]
    int nums[] = {5, 4, 3, 2, 1, 6};
    int start = 1;
    int N = sizeof(nums) / sizeof(nums[0]);
    reachToEnd(nums, N, start);
    return 0;
}

Output

Yes, we can reach to the end node!

Time complexity − O(N) as we process all nodes only once.

Space complexity − O(N) to store nodes into the queue.

In the first approach, we revisit the array elements multiple times, but in the second approach, we revisit the array element only once, which improves the time complexity of the code.

Updated on: 02-Aug-2023

42 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements