📜  最小非零子串,其任何排列都可被2 ^ K整除

📅  最后修改于: 2021-05-04 08:36:46             🧑  作者: Mango

给定长度为N且整数K的二进制字符串S ,任务是找到S的最小非零子字符串,可以将其混杂以产生可被2 K整除的二进制字符串。如果不存在这样的子字符串,则打印-1请注意K始终大于0

例子:

方法:让我们看一看被2 K整除的字符串排列的条件。

  1. 该字符串必须至少具有K个数字0
  2. 该字符串必须至少有一个1

这可以使用两指针技术来实现。对于每个索引i ,尝试找到最小的索引j ,以使子字符串S [i…j-1]满足上述两个条件。
假设左指针指向索引i ,右指针指向j,并且ans存储所需的最小子字符串的长度。
如果不满足条件,则增加j ,否则增加i
在迭代时,找到满足上述两个条件的最小值(j – i)并将其更新为ans = min(ans,j – i)

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the length of the
// smallest substring divisible by 2^k
int findLength(string s, int k)
{
    // To store the final answer
    int ans = INT_MAX;
  
    // Left pointer
    int l = 0;
  
    // Right pointer
    int r = 0;
  
    // Count of the number of zeros and
    // ones in the current substring
    int cnt_zero = 0, cnt_one = 0;
  
    // Loop for two pointers
    while (l < s.size() and r <= s.size()) {
  
        // Condition satisfied
        if (cnt_zero >= k and cnt_one >= 1) {
  
            // Updated the answer
            ans = min(ans, r - l);
  
            // Update the pointer and count
            l++;
            if (s[l - 1] == '0')
                cnt_zero--;
            else
                cnt_one--;
        }
  
        else {
  
            // Update the pointer and count
            if (r == s.size())
                break;
            if (s[r] == '0')
                cnt_zero++;
            else
                cnt_one++;
            r++;
        }
    }
  
    if (ans == INT_MAX)
        return -1;
    return ans;
}
  
// Driver code
int main()
{
    string s = "100";
    int k = 2;
  
    cout << findLength(s, k);
  
    return 0;
}


Java
// Java implementation of the approach 
class GFG 
{
    static final int INT_MAX = Integer.MAX_VALUE;
      
    // Function to return the length of the 
    // smallest substring divisible by 2^k 
    static int findLength(String s, int k) 
    { 
        // To store the final answer 
        int ans = INT_MAX; 
      
        // Left pointer 
        int l = 0; 
      
        // Right pointer 
        int r = 0; 
      
        // Count of the number of zeros and 
        // ones in the current substring 
        int cnt_zero = 0, cnt_one = 0; 
      
        // Loop for two pointers 
        while (l < s.length() && r <= s.length())
        { 
      
            // Condition satisfied 
            if (cnt_zero >= k && cnt_one >= 1)
            { 
      
                // Updated the answer 
                ans = Math.min(ans, r - l); 
      
                // Update the pointer and count 
                l++; 
                if (s.charAt(l - 1) == '0') 
                    cnt_zero--; 
                else
                    cnt_one--; 
            } 
            else
            { 
      
                // Update the pointer and count 
                if (r == s.length()) 
                    break; 
                if (s.charAt(r) == '0') 
                    cnt_zero++; 
                else
                    cnt_one++; 
                r++; 
            } 
        } 
        if (ans == INT_MAX) 
            return -1; 
        return ans; 
    } 
      
    // Driver code 
    public static void main (String[] args) 
    { 
        String s = "100"; 
        int k = 2; 
      
        System.out.println(findLength(s, k)); 
    } 
}
  
// This code is contributed by AnkitRai01


Python3
# Python3 implementation of the approach
  
# Function to return the length of the
# smallest subdivisible by 2^k
def findLength(s, k):
      
    # To store the final answer
    ans = 10**9
  
    # Left pointer
    l = 0
  
    # Right pointer
    r = 0
  
    # Count of the number of zeros and
    # ones in the current substring
    cnt_zero = 0
    cnt_one = 0
  
    # Loop for two pointers
    while (l < len(s) and r <= len(s)):
  
        # Condition satisfied
        if (cnt_zero >= k and cnt_one >= 1):
  
            # Updated the answer
            ans = min(ans, r - l)
  
            # Update the pointer and count
            l += 1
            if (s[l - 1] == '0'):
                cnt_zero -= 1
            else:
                cnt_one -= 1
  
        else:
  
            # Update the pointer and count
            if (r == len(s)):
                break
            if (s[r] == '0'):
                cnt_zero += 1
            else:
                cnt_one += 1
            r += 1
  
    if (ans == 10**9):
        return -1
    return ans
  
# Driver code
s = "100"
k = 2
  
print(findLength(s, k))
  
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach 
using System;
  
class GFG 
{
    static int INT_MAX = int.MaxValue;
      
    // Function to return the length of the 
    // smallest substring divisible by 2^k 
    static int findLength(string s, int k) 
    { 
        // To store the final answer 
        int ans = INT_MAX; 
      
        // Left pointer 
        int l = 0; 
      
        // Right pointer 
        int r = 0; 
      
        // Count of the number of zeros and 
        // ones in the current substring 
        int cnt_zero = 0, cnt_one = 0; 
      
        // Loop for two pointers 
        while (l < s.Length && r <= s.Length)
        { 
      
            // Condition satisfied 
            if (cnt_zero >= k && cnt_one >= 1)
            { 
      
                // Updated the answer 
                ans = Math.Min(ans, r - l); 
      
                // Update the pointer and count 
                l++; 
                if (s[l - 1] == '0') 
                    cnt_zero--; 
                else
                    cnt_one--; 
            } 
            else
            { 
      
                // Update the pointer and count 
                if (r == s.Length) 
                    break; 
                      
                if (s[r] == '0') 
                    cnt_zero++; 
                else
                    cnt_one++; 
                r++; 
            } 
        } 
        if (ans == INT_MAX) 
            return -1; 
              
        return ans; 
    } 
      
    // Driver code 
    public static void Main () 
    { 
        string s = "100"; 
        int k = 2; 
      
        Console.WriteLine(findLength(s, k)); 
    } 
}
  
// This code is contributed by AnkitRai01


输出:
3

时间复杂度: O(N)