📌  相关文章
📜  查找到达字符串结尾的最小步骤数

📅  最后修改于: 2021-04-24 04:54:39             🧑  作者: Mango

给定长度为N且整数K的二进制字符串str ,任务是找到通过以下移动从str [0]str [N – 1]所需的最小步数:

  1. 从索引i来看,唯一有效的移动是i + 1i + 2i + K
  2. 只有在str [i] =’1’时才能访问索引i

例子:

方法:想法是使用动态编程来解决问题。

  • 假定对于任何索引i ,都可以移动到索引i + 1,i + 2或i + K。
  • 三种可能性之一将给出所需的结果,即到达终点的最少步骤数。
  • 因此,将创建dp []数组,并以自下而上的方式填充它。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
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 requried 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 requried 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 requried 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 requried 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


输出:
3

时间复杂度: O(N),其中N是字符串的长度。