给定长度为N且整数K的二进制字符串S ,任务是找到使二进制字符串可被2 K整除所需的最小相邻交换数。如果不可能,则打印-1 。
例子:
Input: S = “100111”, K = 2
Output: 6
Swapping the right-most zero 3 times
to the right, we get “101110”.
Swapping the second right-most zero
3 times to the right, we get “111100”.
Input: S = “1011”, K = 2
Output: -1
方法1:一种方法将从最右边的零交换。因此,让我们将问题改写为更简单的方法。需要最小数量的交换,以便在右端至少提供K个连续的零。
一种方法是模拟交换。从最右边的零开始,交换它直到它的右边有1而不是字符串的末尾。将对K个最右边的零执行此操作。这种方法的时间复杂度将是O(N * K) 。
方法2:在此处取得更好性能的关键是避免进行仿真。
观察:
Among the K right-most zeros, each zero will need to be swapped X number of times, where X is the number of 1s to the right of that zero.
因此,对于K个最右边的零,任务是找到每个右边的1个数的总和。
算法:
- 初始化变量c_zero = 0 , c_one = 0和ans = 0 。
- 从i = N – 1到i = 0运行循环。
- 如果S [i] = 0,则更新c_zero = c_zero + 1和ans = ans + c_one 。
- 如果S [i] = 1,则更新c_one = c_one + 1 。
- 如果c_zero = K,则断开。
- 如果c_zero
则返回-1 。 - 最后,返回ans 。
因此,该方法的时间复杂度将为O(N) 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the minimum swaps required
int findMinSwaps(string s, int k)
{
// To store the final answer
int ans = 0;
// To store the count of one and zero
int c_one = 0, c_zero = 0;
// Loop from end of the string
for (int i = s.size() - 1; i >= 0; i--) {
// If s[i] = 1
if (s[i] == '1')
c_one++;
// If s[i] = 0
if (s[i] == '0')
c_zero++, ans += c_one;
// If c_zero = k
if (c_zero == k)
break;
}
// If the result can't
// be achieved
if (c_zero < k)
return -1;
// Return the final answer
return ans;
}
// Driver code
int main()
{
string s = "100111";
int k = 2;
cout << findMinSwaps(s, k);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the minimum swaps required
static int findMinSwaps(String s, int k)
{
// To store the final answer
int ans = 0;
// To store the count of one and zero
int c_one = 0, c_zero = 0;
// Loop from end of the string
for (int i = s.length() - 1; i >= 0; i--)
{
// If s[i] = 1
if (s.charAt(i) == '1')
c_one++;
// If s[i] = 0
if (s.charAt(i) == '0')
{
c_zero++;
ans += c_one;
}
// If c_zero = k
if (c_zero == k)
break;
}
// If the result can't
// be achieved
if (c_zero < k)
return -1;
// Return the final answer
return ans;
}
// Driver code
public static void main (String[] args)
{
String s = "100111";
int k = 2;
System.out.println(findMinSwaps(s, k));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the approach
# Function to return the minimum swaps required
def findMinSwaps(s, k) :
# To store the final answer
ans = 0;
# To store the count of one and zero
c_one = 0; c_zero = 0;
# Loop from end of the string
for i in range(len(s)-1, -1, -1) :
# If s[i] = 1
if (s[i] == '1') :
c_one += 1;
# If s[i] = 0
if (s[i] == '0') :
c_zero += 1;
ans += c_one;
# If c_zero = k
if (c_zero == k) :
break;
# If the result can't
# be achieved
if (c_zero < k) :
return -1;
# Return the final answer
return ans;
# Driver code
if __name__ == "__main__" :
s = "100111";
k = 2;
print(findMinSwaps(s, k));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the minimum swaps required
static int findMinSwaps(string s, int k)
{
// To store the final answer
int ans = 0;
// To store the count of one and zero
int c_one = 0, c_zero = 0;
// Loop from end of the string
for (int i = s.Length - 1; i >= 0; i--)
{
// If s[i] = 1
if (s[i] == '1')
c_one++;
// If s[i] = 0
if (s[i] == '0')
{
c_zero++;
ans += c_one;
}
// If c_zero = k
if (c_zero == k)
break;
}
// If the result can't
// be achieved
if (c_zero < k)
return -1;
// Return the final answer
return ans;
}
// Driver code
public static void Main()
{
string s = "100111";
int k = 2;
Console.WriteLine(findMinSwaps(s, k));
}
}
// This code is contributed by AnkitRai01
6