Open In App

Find minimum number of steps to reach the end of String

Improve
Improve
Like Article
Like
Save
Share
Report

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: 

  1. From an index i, the only valid moves are i + 1, i + 2 and i + K
  2. An index i can only be visited if str[i] = ‘1’

Examples: 

Input: str = “101000011”, K = 5 
Output:
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:

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++




// 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




// 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




# 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#




// 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


Javascript




<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>


Output

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:

C++




#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;
}


Java




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];
  }
}


Python3




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#




// 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


Javascript




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));


Output

3

Time Complexity: O(N) where N is the length of the string.
Auxiliary Space: O(K) 



Last Updated : 20 Jul, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads