使用无限交换形成的字典上最小的二进制字符串
给定一个长度为N的二进制字符串s ,任务是使用0和1之间的无限次交换来找到字典上最小的字符串。
例子:
Input: s = “1001001”
Output: 0000111
Explanation: Lexicographically smallest string of 1001001 is only 0000111
Input: s = “0001”
Output: 0001
Explanation: Lexicographically smallest string of 0001 is only 0001
Input: s = “1”
Output: 1
Explanation: Lexicographically smallest string of 1 is only 1
天真的方法:解决这个问题的最基本方法是基于以下想法:
Since we are allowed to do infinite swaps between 0s and 1s. Therefore while swapping, we will get one such combination where all 0s will come before all 1s.
As by definition, lexicographically smallest binary string must have all 0s before all 1s, therefore, the above such combination will yield the required output.
现在为了找到这样的组合,我们可以一个一个地交换 0 和 1,直到我们得到所需的组合,其中所有 0 在所有 1 之前。
时间复杂度: O(N!),查找给定二进制字符串的所有此类组合
辅助空间: O(1)
方法 2:根据以下观察,可以通过避免查找所有组合来优化上述方法:
Since we need to find a combination where all 0s come before all 1s, we can sort the given binary string instead, to get the required lexicographically smallest binary string.
时间复杂度: O(N*log(N))
辅助空间: O(1)
有效的方法:通过避免对给定的二进制字符串进行完全排序,可以进一步优化上述方法,如下所示:
Instead of sorting given binary string, we can simply find the count of set and unset bits (0s and 1s) and form a new binary with the same count where all 0s come before all 1s.
基于上述思路,按照以下步骤实现此方法:
- 计算给定二进制字符串中 0 和 1 的数量。
- 创建一个新的空字符串
- 在空字符串中插入 0 等于原始字符串中 0 的计数。
- 然后在新字符串中附加 1 等于原始字符串中 1 的计数。
- 将新字符串作为字典顺序最小的二进制字符串返回。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to find the count of 0s
int countOfXs(string s, char x)
{
int n = s.length();
int no_of_x = 0;
for (int i = 0; i < n; i++) {
// if character is 0
// then increase the count of 0's
if (s[i] == x)
no_of_x++;
}
return no_of_x;
}
// Function to find the lexicographically
// smallest string using infinite swaps
string lexSmallestBinaryString(string s)
{
// Variables to count no of 0 and no of 1
int no_of_0 = countOfXs(s, '0');
int no_of_1 = countOfXs(s, '1');
// Create new string to store
// the required string
s = "";
// Put all 0's first in resultant string
for (int i = 0; i < no_of_0; i++) {
// Make character equal to 0
s += '0';
}
// Append all 1's in resultant string
for (int i = 0; i < no_of_1; i++) {
// Make character equal to 1
s += '1';
}
// Return the resultant string
return s;
}
// Driver code
int main()
{
string s = "1111000011";
cout << lexSmallestBinaryString(s);
return 0;
}
Java
// Java code to implement the approach
class GFG
{
// Function to find the count of 0s
static int countOfXs(String s, char x)
{
int n = s.length();
int no_of_x = 0;
for (int i = 0; i < n; i++)
{
// if character is 0
// then increase the count of 0's
if (s.charAt(i) == x)
no_of_x++;
}
return no_of_x;
}
// Function to find the lexicographically
// smallest string using infinite swaps
static String lexSmallestBinaryString(String s)
{
// Variables to count no of 0 and no of 1
int no_of_0 = countOfXs(s, '0');
int no_of_1 = countOfXs(s, '1');
// Create new string to store
// the required string
s = "";
// Put all 0's first in resultant string
for (int i = 0; i < no_of_0; i++)
{
// Make character equal to 0
s += '0';
}
// Append all 1's in resultant string
for (int i = 0; i < no_of_1; i++)
{
// Make character equal to 1
s += '1';
}
// Return the resultant string
return s;
}
public static void main(String[] args)
{
String s = "1111000011";
System.out.println(lexSmallestBinaryString(s));
}
}
// This code is contributed by phasing17.
C#
// C# code to implement the above approach
using System;
class GFG {
// Function to find the count of 0s
static int countOfXs(string s, char x)
{
int n = s.Length;
int no_of_x = 0;
for (int i = 0; i < n; i++) {
// if character is 0
// then increase the count of 0's
if (s[i] == x)
no_of_x++;
}
return no_of_x;
}
// Function to find the lexicographically
// smallest string using infinite swaps
static string lexSmallestBinaryString(string s)
{
// Variables to count no of 0 and no of 1
int no_of_0 = countOfXs(s, '0');
int no_of_1 = countOfXs(s, '1');
// Create new string to store
// the required string
s = "";
// Put all 0's first in resultant string
for (int i = 0; i < no_of_0; i++) {
// Make character equal to 0
s += '0';
}
// Append all 1's in resultant string
for (int i = 0; i < no_of_1; i++) {
// Make character equal to 1
s += '1';
}
// Return the resultant string
return s;
}
// Driver code
public static void Main()
{
string s = "1111000011";
Console.Write(lexSmallestBinaryString(s));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
0000111111
时间复杂度: O(N)
辅助空间: O(1)