Minimize the number of steps required to reach the end of the array

Given an integer array arr[] of length N consisting of positive integers, the task is to minimize the number of steps required to reach the index ‘N-1’. At a given step if we are at index ‘i’ we can go to index ‘i-arr[i]’ or ‘i+arr[i]’ given we have not visited those indexes before. Also, we cannot go outside the bounds of the array. Print -1 if there is not possible way.

Examples:

Input : arr[] = {1, 1, 1}
Output : 2
The path will be 0 -> 1 -> 2.
Step 1 - 0 to 1
Step 2 - 1 to 2

Input : {2, 1}
Output : -1

This problem can be solved using dynamic programming approach.

Let’s discuss an approach that might seem correct at start. Let’s suppose we are at ith index. Can we directly say that dp[i] = 1 + min( dp[i-arr[i]], dp[i+arr[i]] ) ?

No, we cannot. The path we took to reach the index ‘i’ also matters as indexes we used before won’t be available to visit anymore.

Thus, the only approach we are left with is trying out all the possible combinations which can be really large. In this article, we will use bit-masking approach to reduce the complexity to exponential. Our mask will be an integer value with the following features.

1) If, a index 'i' is visited, ith bit 
   will be set 1 in the mask. 
2) Else that bit will be set 0.

The required recurrence relation will be.

dp[i][mask] = 1 + min(dp[i+arr[i]][mask|(1<<i)], 
                      dp[i-arr[i]][mask|(1<<i)])

Below is the implementation of the above approach:

CPP

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the above approach
  
#include <bits/stdc++.h>
#define maxLen 10
#define maskLen 130
using namespace std;
  
// variable to store states of dp
int dp[maxLen][maskLen];
  
// variable to check if a given state
// has been solved
bool v[maxLen][maskLen];
  
// Function to find the minimum number of steps 
// required to reach the end of the array
int minSteps(int arr[], int i, int mask, int n)
{
    // base case
    if (i == n - 1)
        return 0;
  
    if (i > n - 1 || i < 0)
        return 9999999;
    if ((mask >> i) & 1)
        return 9999999;
  
    // to check if a state has
    // been solved
    if (v[i][mask])
        return dp[i][mask];
    v[i][mask] = 1;
  
    // required recurrence relation
    dp[i][mask] = 1 + min(minSteps(arr, i - arr[i], (mask | (1 << i)), n), 
                          minSteps(arr, i + arr[i], (mask | (1 << i)), n));
  
    // returning the value
    return dp[i][mask];
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 2, 2, 1, 1 };
  
    int n = sizeof(arr) / sizeof(int);
  
    int ans = minSteps(arr, 0, 0, n);
    if (ans >= 9999999)
        cout << -1;
    else
        cout << ans;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the above approach
  
class GFG
{
  
    static int maxLen = 10;
    static int maskLen = 130;
  
    // variable to store states of dp
    static int[][] dp = new int[maxLen][maskLen];
  
    // variable to check if a given state
    // has been solved
    static boolean[][] v = new boolean[maxLen][maskLen];
  
    // Function to find the minimum number of steps 
    // required to reach the end of the array
    static int minSteps(int arr[], int i, int mask, int n) 
    {
        // base case
        if (i == n - 1)
        {
            return 0;
        }
  
        if (i > n - 1 || i < 0
        {
            return 9999999;
        }
        if ((mask >> i) % 2 == 1
        {
            return 9999999;
        }
  
        // to check if a state has
        // been solved
        if (v[i][mask])
        {
            return dp[i][mask];
        }
        v[i][mask] = true;
  
        // required recurrence relation
        dp[i][mask] = 1 + Math.min(minSteps(arr, i - arr[i], (mask | (1 << i)), n),
                                minSteps(arr, i + arr[i], (mask | (1 << i)), n));
  
        // returning the value
        return dp[i][mask];
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        int arr[] = {1, 2, 2, 2, 1, 1};
  
        int n = arr.length;
  
        int ans = minSteps(arr, 0, 0, n);
        if (ans >= 9999999
        {
            System.out.println(-1);
        }
        else
        {
            System.out.println(ans);
        }
    }
}
  
/* This code contributed by PrinciRaj1992 */

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the above approach
maxLen = 10
maskLen = 130
  
  
# variable to store states of dp
dp = [[ 0 for i in range(maskLen)] for i in range(maxLen)]
  
# variable to check if a given state
# has been solved
v = [[False for i in range(maskLen)] for i in range(maxLen)]
  
# Function to find the minimum number of steps 
# required to reach the end of the array
def minSteps(arr, i, mask, n):
  
    # base case
    if (i == n - 1):
        return 0
  
    if (i > n - 1 or i < 0):
        return 9999999
  
    if ((mask >> i) & 1):
        return 9999999
  
    # to check if a state has
    # been solved
    if (v[i][mask] == True):
        return dp[i][mask]
    v[i][mask] = True
  
    # required recurrence relation
    dp[i][mask] = 1 + min(minSteps(arr, i - arr[i], (mask | (1 << i)), n), 
                        minSteps(arr, i + arr[i], (mask | (1 << i)), n))
  
    # returning the value
    return dp[i][mask]
  
  
# Driver code
  
arr=[1, 2, 2, 2, 1, 1]
  
n = len(arr)
  
ans = minSteps(arr, 0, 0, n)
  
if (ans >= 9999999):
    print(-1)
else:
    print(ans)
      
# This code is contributed by mohit kumar 29    

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the above approach
using System;
  
class GFG
{
      
    static int maxLen = 10;
    static int maskLen = 130;
  
    // variable to store states of dp
    static int[,] dp = new int[maxLen, maskLen];
  
    // variable to check if a given state
    // has been solved
    static bool[,] v = new bool[maxLen, maskLen];
  
    // Function to find the minimum number of steps 
    // required to reach the end of the array
    static int minSteps(int []arr, int i, int mask, int n) 
    {
        // base case
        if (i == n - 1)
        {
            return 0;
        }
  
        if (i > n - 1 || i < 0) 
        {
            return 9999999;
        }
        if ((mask >> i) % 2 == 1) 
        {
            return 9999999;
        }
  
        // to check if a state has
        // been solved
        if (v[i, mask])
        {
            return dp[i, mask];
        }
        v[i, mask] = true;
  
        // required recurrence relation
        dp[i,mask] = 1 + Math.Min(minSteps(arr, i - arr[i], (mask | (1 << i)), n),
                                minSteps(arr, i + arr[i], (mask | (1 << i)), n));
  
        // returning the value
        return dp[i,mask];
    }
  
    // Driver code
    static public void Main ()
    {
        int []arr = {1, 2, 2, 2, 1, 1};
  
        int n = arr.Length;
  
        int ans = minSteps(arr, 0, 0, n);
        if (ans >= 9999999) 
        {
            Console.WriteLine(-1);
        }
        else
        {
            Console.WriteLine(ans);
        }
    }
}
  
/* This code contributed by ajit. */

chevron_right


Output:

3

Time Complexity: O(N*(2N))



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.