📜  进行最少的删除,以使字符串由0s的子字符串和随后的1s的子字符串串联而成

📅  最后修改于: 2021-04-26 06:52:57             🧑  作者: Mango

给定长度为N的二进制字符串str ,任务是找到从给定的二进制字符串删除的最小数目的字符,以使子字符串为0 s,然后子字符串为1 s。

例子:

天真的方法:解决此问题的最简单方法是遍历字符串,对于遇到的每个“ 1” ,通过删除0 s或删除1 s计算所需的最小删除次数。最后,打印所需的最少删除内容。

时间复杂度: O(N 2 )
辅助空间: O(1)

高效的方法:可以通过有一个辅助空间来优化上述方法,该辅助空间可以使1s之后的0s计数保持不变。使用这种预计算,可以将时间复杂度提高N倍。步骤如下:

  • 初始化一个变量,例如ans ,以存储需要删除的最少字符数。
  • 初始化一个数组,比如zeroCount [] ,以计算在给定索引之后出现的0数。
  • 从端部超过[N – 2,0]的范围内遍历字符串str并且如果当前字符是0,则更新zeroCount [I]作为(zeroCount [I + 1] + 1)。否则,将zeroCount [i]更新为zeroCount [i + 1]
  • 初始化一个变量,例如oneCount ,以计算1s的数量。
  • 再次遍历给定的字符串。为每个字符发现是‘1’,更新ANS作为最小ANS的和(oneCount + zeroCount [I])。
  • 完成上述步骤后,如果ans的值与其初始值相同,则需要删除0个字符。否则, ans是要删除的所需字符数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
#include 
 
using namespace std;
 
// Function to count minimum removals
// required to make a given string
// concatenation of substring of 0s
// followed by substring of 1s
int minimumDeletions(string s)
{
     
    // Stores the length of the string
    int n = s.size();
 
    // Precompute the count of 0s
    int zeroCount[n];
 
    // Check for the last character
    zeroCount[n - 1] = (s[n - 1] == '0') ? 1 : 0;
 
    // Traverse and update zeroCount array
    for(int i = n - 2; i >= 0; i--)
     
        // If current character is 0,
        zeroCount[i] = (s[i] == '0') ?
 
                       // Update aCount[i] as
                       // aCount[i + 1] + 1
                       zeroCount[i + 1] + 1 :
 
                       // Update as aCount[i + 1]
                       zeroCount[i + 1];
 
    // Keeps track of deleted 1s
    int oneCount = 0;
 
    // Stores the count of removals
    int ans = INT_MAX;
 
    // Traverse the array
    for(int i = 0; i < n; i++)
    {
         
        // If current character is 1
        if (s[i] == '1')
        {
             
            // Update ans
            ans = min(ans,
                      oneCount + 
                      zeroCount[i]);
            oneCount++;
        }
    }
 
    // If all 1s are deleted
    ans = min(ans, oneCount);
 
    // Return the minimum
    // number of deletions
    return (ans == INT_MAX) ? 0 : ans;
}
 
// Driver Code
int main()
{
    string stri = "00101101";
     
    cout << minimumDeletions(stri) << endl;
     
    return 0;
}
 
// This code is contributed by AnkThon


Java
// Java program for the above approach
 
import java.io.*;
 
class GFG {
 
    // Function to count minimum removals
    // required to make a given string
    // concatenation of substring of 0s
    // followed by substring of 1s
    public static int minimumDeletions(String s)
    {
        // Stores the length of the string
        int n = s.length();
 
        // Precompute the count of 0s
        int zeroCount[] = new int[n];
 
        // Check for the last character
        zeroCount[n - 1] = (s.charAt(n - 1)
                            == '0')
                               ? 1
                               : 0;
 
        // Traverse and update zeroCount array
        for (int i = n - 2; i >= 0; i--)
 
            // If current character is 0,
            zeroCount[i] = (s.charAt(i) == '0')
 
                               // Update aCount[i] as
                               // aCount[i + 1] + 1
                               ? zeroCount[i + 1] + 1
 
                               // Update as aCount[i + 1]
                               : zeroCount[i + 1];
 
        // Keeps track of deleted 1s
        int oneCount = 0;
 
        // Stores the count of removals
        int ans = Integer.MAX_VALUE;
 
        // Traverse the array
        for (int i = 0; i < n; i++) {
 
            // If current character is 1
            if (s.charAt(i) == '1') {
 
                // Update ans
                ans = Math.min(ans,
                               oneCount
                                   + zeroCount[i]);
                oneCount++;
            }
        }
 
        // If all 1s are deleted
        ans = Math.min(ans, oneCount);
 
        // Return the minimum
        // number of deletions
        return (ans == Integer.MAX_VALUE)
            ? 0
            : ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String str = "00101101";
        System.out.println(
            minimumDeletions(str));
    }
}


Python3
# Python3 program for the above approach
 
# Function to count minimum removals
# required to make a given string
# concatenation of substring of 0s
# followed by substring of 1s
def minimumDeletions(s):
     
    # Stores the length of the string
    n = len(s)
 
    # Precompute the count of 0s
    zeroCount = [ 0 for i in range(n)]
 
    # Check for the last character
    zeroCount[n - 1] = 1 if s[n - 1] == '0' else 0
 
    # Traverse and update zeroCount array
    for i in range(n - 2, -1, -1):
 
        # If current character is 0,
        zeroCount[i] = zeroCount[i + 1] + 1 if (s[i] == '0') else zeroCount[i + 1]
 
    # Keeps track of deleted 1s
    oneCount = 0
 
    # Stores the count of removals
    ans = 10**9
 
    # Traverse the array
    for i in range(n):
 
        # If current character is 1
        if (s[i] == '1'):
 
            # Update ans
            ans = min(ans,oneCount + zeroCount[i])
            oneCount += 1
 
    # If all 1s are deleted
    ans = min(ans, oneCount)
 
    # Return the minimum
    # number of deletions
    return 0 if ans == 10**18 else ans
 
# Driver Code
if __name__ == '__main__':
    str = "00101101"
    print(minimumDeletions(str))
 
    # This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
 
    // Function to count minimum removals
    // required to make a given string
    // concatenation of substring of 0s
    // followed by substring of 1s
    public static int minimumDeletions(String s)
    {
        // Stores the length of the string
        int n = s.Length;
 
        // Precompute the count of 0s
        int []zeroCount = new int[n];
 
        // Check for the last character
        zeroCount[n - 1] = (s[n - 1]
                            == '0')
                               ? 1
                               : 0;
 
        // Traverse and update zeroCount array
        for (int i = n - 2; i >= 0; i--)
 
            // If current character is 0,
            zeroCount[i] = (s[i] == '0')
 
                               // Update aCount[i] as
                               // aCount[i + 1] + 1
                               ? zeroCount[i + 1] + 1
 
                               // Update as aCount[i + 1]
                               : zeroCount[i + 1];
 
        // Keeps track of deleted 1s
        int oneCount = 0;
 
        // Stores the count of removals
        int ans = int.MaxValue;
 
        // Traverse the array
        for (int i = 0; i < n; i++) {
 
            // If current character is 1
            if (s[i] == '1') {
 
                // Update ans
                ans = Math.Min(ans,
                               oneCount
                                   + zeroCount[i]);
                oneCount++;
            }
        }
 
        // If all 1s are deleted
        ans = Math.Min(ans, oneCount);
 
        // Return the minimum
        // number of deletions
        return (ans == int.MaxValue)
            ? 0
            : ans;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        String str = "00101101";
        Console.WriteLine(
            minimumDeletions(str));
    }
}
 
// This code is contributed by 29AjayKumar


输出:
2

时间复杂度: O(N)
辅助空间: O(N)