给定长度为N且整数K的二进制字符串S ,任务是找到S的最小非零子字符串,可以将其混杂以产生可被2 K整除的二进制字符串。如果不存在这样的子字符串,则打印-1 。请注意, K始终大于0 。
例子:
Input: S = “100”, k = 1
Output: 2
Smallest substring that can be jumbled is “10”.
Thus, the answer is 2.
Input: S = “1111”, k = 2
Output: -1
方法:让我们看一看被2 K整除的字符串排列的条件。
- 该字符串必须至少具有K个数字0 。
- 该字符串必须至少有一个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)