Given a binary string str of length N and an integer K, the task is to find the minimum number of steps required to move from str[0] to str[N – 1] with the following moves:
- From an index i, the only valid moves are i + 1, i + 2 and i + K
- An index i can only be visited if str[i] = ‘1’
Examples:
Input: str = “101000011”, K = 5
Output: 3
str[0] -> str[2] -> str[7] -> str[8]
Input: str = “1100000100111”, K = 6
Output: -1
There is no possible path.
Input: str = “10101010101111010101”, K = 4
Output: 6
Approach: The idea is to use dynamic programming to solve the problem.
- It is given that for any index i, it is possible to move to an index i+1, i+2 or i+K.
- One of the three possibilities will give the required result which is the minimum number of steps to reach the end.
- Therefore, the dp[] array is created and is filled in a bottom-up manner.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to return the minimum number // of steps to reach the end int minSteps(string str, int n, int k)
{ // If the end can't be reached
if (str[n - 1] == '0' )
return -1;
// Already at the end
if (n == 1)
return 0;
// If the length is 2 or 3 then the end
// can be reached in a single step
if (n < 4)
return 1;
// For the other cases, solve the problem
// using dynamic programming
int dp[n];
// It requires no move from the
// end to reach the end
dp[n - 1] = 0;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[n - 2] = 1;
dp[n - 3] = 1;
// Update the answer for every index
for ( int i = n - 4; i >= 0; i--) {
// If the current index is not reachable
if (str[i] == '0' )
continue ;
// To store the minimum steps required
// from the current index
int steps = INT_MAX;
// If it is a valid move then update
// the minimum steps required
if (i + k < n && str[i + k] == '1' )
steps = min(steps, dp[i + k]);
if (str[i + 1] == '1' )
steps = min(steps, dp[i + 1]);
if (str[i + 2] == '1' )
steps = min(steps, dp[i + 2]);
// Update the minimum steps required starting
// from the current index
dp[i] = (steps == INT_MAX) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[0] == INT_MAX)
return -1;
// Return the minimum steps required
return dp[0];
} // Driver code int main()
{ string str = "101000011" ;
int n = str.length();
int k = 5;
cout << minSteps(str, n, k);
return 0;
} |
// Java implementation of the approach class GFG
{ final static int INT_MAX = Integer.MAX_VALUE ;
// Function to return the minimum number
// of steps to reach the end
static int minSteps(String str, int n, int k)
{
// If the end can't be reached
if (str.charAt(n - 1 ) == '0' )
return - 1 ;
// Already at the end
if (n == 1 )
return 0 ;
// If the length is 2 or 3 then the end
// can be reached in a single step
if (n < 4 )
return 1 ;
// For the other cases, solve the problem
// using dynamic programming
int dp[] = new int [n];
// It requires no move from the
// end to reach the end
dp[n - 1 ] = 0 ;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[n - 2 ] = 1 ;
dp[n - 3 ] = 1 ;
// Update the answer for every index
for ( int i = n - 4 ; i >= 0 ; i--)
{
// If the current index is not reachable
if (str.charAt(i) == '0' )
continue ;
// To store the minimum steps required
// from the current index
int steps =INT_MAX ;
// If it is a valiINT_MAXd move then update
// the minimum steps required
if (i + k < n && str.charAt(i + k) == '1' )
steps = Math.min(steps, dp[i + k]);
if (str.charAt(i + 1 ) == '1' )
steps = Math.min(steps, dp[i + 1 ]);
if (str.charAt(i + 2 ) == '1' )
steps = Math.min(steps, dp[i + 2 ]);
// Update the minimum steps required starting
// from the current index
dp[i] = (steps == INT_MAX) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[ 0 ] == INT_MAX)
return - 1 ;
// Return the minimum steps required
return dp[ 0 ];
}
// Driver code
public static void main(String[] args)
{
String str = "101000011" ;
int n = str.length();
int k = 5 ;
System.out.println(minSteps(str, n, k));
}
} // This code is contributed by AnkitRai01 |
# Python3 implementation of the approach import sys
INT_MAX = sys.maxsize;
# Function to return the minimum number # of steps to reach the end def minSteps(string , n, k) :
# If the end can't be reached
if (string[n - 1 ] = = '0' ) :
return - 1 ;
# Already at the end
if (n = = 1 ) :
return 0 ;
# If the length is 2 or 3 then the end
# can be reached in a single step
if (n < 4 ) :
return 1 ;
# For the other cases, solve the problem
# using dynamic programming
dp = [ 0 ] * n;
# It requires no move from the
# end to reach the end
dp[n - 1 ] = 0 ;
# From the 2nd last and the 3rd last
# index, only a single move is required
dp[n - 2 ] = 1 ;
dp[n - 3 ] = 1 ;
# Update the answer for every index
for i in range (n - 4 , - 1 , - 1 ) :
# If the current index is not reachable
if (string[i] = = '0' ) :
continue ;
# To store the minimum steps required
# from the current index
steps = INT_MAX;
# If it is a valid move then update
# the minimum steps required
if (i + k < n and string[i + k] = = '1' ) :
steps = min (steps, dp[i + k]);
if (string[i + 1 ] = = '1' ) :
steps = min (steps, dp[i + 1 ]);
if (string[i + 2 ] = = '1' ) :
steps = min (steps, dp[i + 2 ]);
# Update the minimum steps required starting
# from the current index
dp[i] = steps if (steps = = INT_MAX) else ( 1 + steps);
# Cannot reach the end starting from str[0]
if (dp[ 0 ] = = INT_MAX) :
return - 1 ;
# Return the minimum steps required
return dp[ 0 ];
# Driver code if __name__ = = "__main__" :
string = "101000011" ;
n = len (string);
k = 5 ;
print (minSteps(string, n, k));
# This code is contributed by AnkitRai01 |
// C# implementation of the approach using System;
class GFG
{ static int INT_MAX = int .MaxValue ;
// Function to return the minimum number
// of steps to reach the end
static int minSteps( string str, int n, int k)
{
// If the end can't be reached
if (str[n - 1] == '0' )
return -1;
// Already at the end
if (n == 1)
return 0;
// If the length is 2 or 3 then the end
// can be reached in a single step
if (n < 4)
return 1;
// For the other cases, solve the problem
// using dynamic programming
int []dp = new int [n];
// It requires no move from the
// end to reach the end
dp[n - 1] = 0;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[n - 2] = 1;
dp[n - 3] = 1;
// Update the answer for every index
for ( int i = n - 4; i >= 0; i--)
{
// If the current index is not reachable
if (str[i] == '0' )
continue ;
// To store the minimum steps required
// from the current index
int steps = INT_MAX ;
// If it is a valiINT_MAXd move then update
// the minimum steps required
if (i + k < n && str[i + k] == '1' )
steps = Math.Min(steps, dp[i + k]);
if (str[i + 1] == '1' )
steps = Math.Min(steps, dp[i + 1]);
if (str[i + 2] == '1' )
steps = Math.Min(steps, dp[i + 2]);
// Update the minimum steps required starting
// from the current index
dp[i] = (steps == INT_MAX) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[0] == INT_MAX)
return -1;
// Return the minimum steps required
return dp[0];
}
// Driver code
public static void Main()
{
string str = "101000011" ;
int n = str.Length;
int k = 5;
Console.WriteLine(minSteps(str, n, k));
}
} // This code is contributed by AnkitRai01 |
<script> // Javascript implementation of the approach // Function to return the minimum number // of steps to reach the end function minSteps(str, n, k)
{ // If the end can't be reached
if (str[n - 1] == '0 ')
return -1;
// Already at the end
if (n == 1)
return 0;
// If the length is 2 or 3 then the end
// can be reached in a single step
if (n < 4)
return 1;
// For the other cases, solve the problem
// using dynamic programming
var dp = Array(n);
// It requires no move from the
// end to reach the end
dp[n - 1] = 0;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[n - 2] = 1;
dp[n - 3] = 1;
// Update the answer for every index
for (var i = n - 4; i >= 0; i--) {
// If the current index is not reachable
if (str[i] == ' 0 ')
continue;
// To store the minimum steps required
// from the current index
var steps = 1000000000;
// If it is a valid move then update
// the minimum steps required
if (i + k < n && str[i + k] == ' 1 ')
steps = Math.min(steps, dp[i + k]);
if (str[i + 1] == ' 1 ')
steps = Math.min(steps, dp[i + 1]);
if (str[i + 2] == ' 1')
steps = Math.min(steps, dp[i + 2]);
// Update the minimum steps required starting
// from the current index
dp[i] = (steps == 1000000000) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[0] == 1000000000)
return -1;
// Return the minimum steps required
return dp[0];
} // Driver code var str = "101000011" ;
var n = str.length;
var k = 5;
document.write( minSteps(str, n, k)); // This code is contributed by famously. </script> |
3
Time Complexity: O(N) where N is the length of the string.
Auxiliary Space: O(N) as it is using extra space for array “dp”
Efficient approach: Space optimization
To optimize space, we can use a rolling array of size k instead of an array of size n to store the dynamic programming values. Since we only need to access values up to k positions ahead, we can reuse the same array to store values for the next iteration.
Implementation Steps:
- Create a function minSteps and initialize all base cases.
- Create a DP vector of size K.
- Iterate the array and update the answer for every index
- initialize a variable steps to store the minimum steps required from the current index.
- Now If it is a valid move then update the minimum steps required and update the steps accordingly.
- At last return minimum steps required if dp[0] is not INT_MAX else return -1.
Implementation:
#include <bits/stdc++.h> using namespace std;
// Function to return the minimum number // of steps to reach the end int minSteps(string str, int n, int k)
{ // If the end can't be reached
if (str[n - 1] == '0' )
return -1;
// Already at the end
if (n == 1)
return 0;
if (n < 4)
return 1;
// initialize dp of required size K
int dp[k];
// It requires no move from the
// end to reach the end
dp[k - 1] = 0;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[k - 2] = 1;
dp[k - 3] = 1;
// Update the answer for every index
for ( int i = n - 4; i >= 0; i--) {
if (str[i] == '0' )
continue ;
// To store the minimum steps required
// from the current index
int steps = INT_MAX;
// If it is a valid move then update
// the minimum steps required
if (i + k < n && str[i + k] == '1' )
steps = min(steps, dp[(i + k) % k]);
if (str[i + 1] == '1' )
steps = min(steps, dp[(i + 1) % k]);
if (str[i + 2] == '1' )
steps = min(steps, dp[(i + 2) % k]);
// Update the minimum steps required starting
// from the current index
dp[i % k] = (steps == INT_MAX) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[0] == INT_MAX)
return -1;
// Return the minimum steps required
return dp[0];
} // Driver code int main()
{ string str = "101000011" ;
int n = str.length();
int k = 5;
cout << minSteps(str, n, k);
return 0;
} |
import java.util.*;
class Main {
public static void main(String[] args)
{
String str = "101000011" ;
int n = str.length();
int k = 5 ;
System.out.println(minSteps(str, n, k));
}
// Function to return the minimum number
// of steps to reach the end
public static int minSteps(String str, int n, int k)
{
// If the end can't be reached
if (str.charAt(n - 1 ) == '0' )
return - 1 ;
// Already at the end
if (n == 1 )
return 0 ;
if (n < 4 )
return 1 ;
// initialize dp of required size K
int [] dp = new int [k];
// It requires no move from the
// end to reach the end
dp[k - 1 ] = 0 ;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[k - 2 ] = 1 ;
dp[k - 3 ] = 1 ;
// Update the answer for every index
for ( int i = n - 4 ; i >= 0 ; i--) {
if (str.charAt(i) == '0' )
continue ;
// To store the minimum steps required
// from the current index
int steps = Integer.MAX_VALUE;
// If it is a valid move then update
// the minimum steps required
if (i + k < n && str.charAt(i + k) == '1' )
steps = Math.min(steps, dp[(i + k) % k]);
if (str.charAt(i + 1 ) == '1' )
steps = Math.min(steps, dp[(i + 1 ) % k]);
if (str.charAt(i + 2 ) == '1' )
steps = Math.min(steps, dp[(i + 2 ) % k]);
// Update the minimum steps required starting
// from the current index
dp[i % k] = (steps == Integer.MAX_VALUE)
? steps
: 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[ 0 ] == Integer.MAX_VALUE)
return - 1 ;
// Return the minimum steps required
return dp[ 0 ];
}
} |
import sys
# Function to return the minimum number of steps to reach the end def minSteps( str , n, k):
# If the end can't be reached
if str [n - 1 ] = = '0' :
return - 1
# Already at the end
if n = = 1 :
return 0
if n < 4 :
return 1
# initialize dp of required size K
dp = [ 0 ] * k
# It requires no move from the end to reach the end
dp[k - 1 ] = 0
# From the 2nd last and the 3rd last index, only a single move is required
dp[k - 2 ] = 1
dp[k - 3 ] = 1
# Update the answer for every index
for i in range (n - 4 , - 1 , - 1 ):
if str [i] = = '0' :
continue
# To store the minimum steps required from the current index
steps = sys.maxsize
# If it is a valid move then update the minimum steps required
if i + k < n and str [i + k] = = '1' :
steps = min (steps, dp[(i + k) % k])
if str [i + 1 ] = = '1' :
steps = min (steps, dp[(i + 1 ) % k])
if str [i + 2 ] = = '1' :
steps = min (steps, dp[(i + 2 ) % k])
# Update the minimum steps required starting from the current index
dp[i % k] = (steps if steps = = sys.maxsize else 1 + steps)
# Cannot reach the end starting from str[0]
if dp[ 0 ] = = sys.maxsize:
return - 1
# Return the minimum steps required
return dp[ 0 ]
# Driver code str = "101000011"
n = len ( str )
k = 5
print (minSteps( str , n, k))
|
// C# implementation of the approach using System;
class GFG
{ // Function to return the minimum number
// of steps to reach the end
static int minSteps( string str, int n, int k)
{
// If the end can't be reached
if (str[n - 1] == '0' )
return -1;
// Already at the end
if (n == 1)
return 0;
if (n < 4)
return 1;
// initialize dp of required size K
int []dp= new int [k];
// It requires no move from the
// end to reach the end
dp[k - 1] = 0;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[k - 2] = 1;
dp[k - 3] = 1;
// Update the answer for every index
for ( int i = n - 4; i >= 0; i--) {
if (str[i] == '0' )
continue ;
// To store the minimum steps required
// from the current index
int steps = int .MaxValue ;
// If it is a valid move then update
// the minimum steps required
if (i + k < n && str[i + k] == '1' )
steps = Math.Min(steps, dp[(i + k) % k]);
if (str[i + 1] == '1' )
steps = Math.Min(steps, dp[(i + 1) % k]);
if (str[i + 2] == '1' )
steps = Math.Min(steps, dp[(i + 2) % k]);
// Update the minimum steps required starting
// from the current index
dp[i % k] = (steps == int .MaxValue) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[0] == int .MaxValue)
return -1;
// Return the minimum steps required
return dp[0];
}
// Driver code
public static void Main()
{
string str = "101000011" ;
int n = str.Length;
int k = 5;
Console.WriteLine(minSteps(str, n, k));
}
} // This code is contributed by panwar2001 |
function minSteps(str, n, k) {
// If the end can't be reached
if (str[n - 1] == '0 ')
return -1;
// Already at the end
if (n == 1)
return 0;
if (n < 4)
return 1;
// initialize dp of required size K
let dp = new Array(k);
// It requires no move from the
// end to reach the end
dp[k - 1] = 0;
// From the 2nd last and the 3rd last
// index, only a single move is required
dp[k - 2] = 1;
dp[k - 3] = 1;
// Update the answer for every index
for (let i = n - 4; i >= 0; i--) {
if (str[i] == ' 0 ')
continue;
// To store the minimum steps required
// from the current index
let steps = Number.MAX_SAFE_INTEGER;
// If it is a valid move then update
// the minimum steps required
if (i + k < n && str[i + k] == ' 1 ')
steps = Math.min(steps, dp[(i + k) % k]);
if (str[i + 1] == ' 1 ')
steps = Math.min(steps, dp[(i + 1) % k]);
if (str[i + 2] == ' 1')
steps = Math.min(steps, dp[(i + 2) % k]);
// Update the minimum steps required starting
// from the current index
dp[i % k] = (steps == Number.MAX_SAFE_INTEGER) ? steps : 1 + steps;
}
// Cannot reach the end starting from str[0]
if (dp[0] == Number.MAX_SAFE_INTEGER)
return -1;
// Return the minimum steps required
return dp[0];
} // Driver code let str = "101000011" ;
let n = str.length; let k = 5; console.log(minSteps(str, n, k)); |
3
Time Complexity: O(N) where N is the length of the string.
Auxiliary Space: O(K)