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
// 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; } |
Java
// 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 */ |
Python
# 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 |
C#
// 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. */ |
Javascript
<script> // Javascript implementation of // the above approach let maxLen = 10; let maskLen = 130; // variable to store states of dp let dp = new Array(maxLen); for (let i = 0; i < maxLen; i++) { dp[i] = new Array(maskLen); } // variable to check if a given state // has been solved let v = new Array(maxLen); for (let i = 0; i < maxLen; i++) { v[i] = new Array(maskLen); } // Function to find the minimum number of steps // required to reach the end of the array function minSteps(arr, i, mask, 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]; } let arr = [1, 2, 2, 2, 1, 1]; let n = arr.length; let ans = minSteps(arr, 0, 0, n); if (ans >= 9999999) { document.write(-1); } else { document.write(ans); } </script> |
3
Time Complexity: O(N*(2N))
Auxiliary Space: O(maxLen + maskLen)
Please Login to comment...