查找大小最多为 3N 的二进制字符串,其中包含至少 2 个给定大小为 2N 的字符串作为子序列
给定三个二进制字符串a 、 b和c ,每个字符串都有2*N 个字符,任务是找到一个几乎有3*N个字符的字符串,使得给定三个字符串中的至少两个作为其子序列之一出现。
例子:
Input: a = “00”, b = “11”, c = “01”
Output: “010”
Explanation: The strings “00” and “01” are subsequences of string “010” and is has not more than 3*N characters. Also, “001”, “011” can be the possible answers.
Input: a = “011001”, b = “111010”, c = “010001”
Output: “011001010″
Explanation: Here, all the three given strings occur as the subsequences of the output string.
方法:给定的问题可以通过以下观察来解决:
- 可以看出,根据鸽洞原理,必须存在一组两个字符串,使得两个字符串中出现频率最高的字符相同,并且出现频率>=N 。
- 因此,对于两个这样的字符串,可以创建一个由N个最常见字符组成的字符串。两个字符串的其余N个字符可以按照出现的顺序分别追加到字符串中。因此,结果字符串的最大大小最多为3*N 。
因此,在找到具有相同最频繁元素的字符串集合后,其余的可以使用双指针方法解决。维护两个指针,每个字符串一个,并按照以下步骤操作:
- 最初, i =0和j = 0 ,其中i表示第一个字符串s1 , j表示第二个字符串s2 。
- 如果s1[i]不等于最常见的字符,则打印s1[i]并增加i 。
- 如果s2[j]不等于最常见的字符,则打印s2[i]并增加j 。
- 如果s1[i]和s2[j]都代表最常见的字符,则打印s1[i]并同时增加i和j 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find most frequent
// character in the given string
char MostFrequent(string s)
{
// Stores the frequency of
// 0 and 1 respectively
int arr[] = { 0, 0 };
for (char ch : s) {
arr[ch - '0']++;
}
// Stores most frequent character
char result = arr[0] > arr[1] ? '0' : '1';
// Return Answer
return result;
}
// Function to find a Binary String of
// at most 3N characters having at least
// two of the given three strings of 2N
// characters as one of its subsequence
void findStr(string& a, string& b, string& c)
{
// Stores most frequent char
char freq;
// Stores the respective string
// with most frequent values
string s1, s2;
// Code to find the set of
// two strings with same
// most frequent characters
if (MostFrequent(a) == MostFrequent(b)) {
s1 = a;
s2 = b;
freq = MostFrequent(a);
}
else if (MostFrequent(a) == MostFrequent(c)) {
s1 = a;
s2 = c;
freq = MostFrequent(a);
}
else {
s1 = b;
s2 = c;
freq = MostFrequent(b);
}
// Pointer to iterate strings
int i = 0, j = 0;
// Traversal using the
// two-pointer approach
while (i < s1.size() && j < s2.size()) {
// if current character
// is not most frequent
while (i < s1.size() && s1[i] != freq) {
cout << s1[i++];
}
// if current character
// is not most frequent
while (j < s2.size() && s2[j] != freq) {
cout << s2[j++];
}
// If end of string is reached
if (i == s1.size() || j == s2.size())
break;
// If both string character
// are same as most frequent
if (s1[i] == s2[j]) {
cout << s1[i];
i++;
j++;
}
else {
cout << s1[i];
i++;
}
}
// Print leftover characters
// of the string s1
while (i < s1.size()) {
cout << s1[i++];
}
// Print leftover characters
// of the string s2
while (j < s2.size()) {
cout << s2[j++];
}
}
// Driver Code
int main()
{
string a, b, c;
a = "00";
b = "11";
c = "01";
findStr(a, b, c);
return 0;
}
Java
// Java program for the above approach
class GFG
{
// Function to find most frequent
// character in the given String
static char MostFrequent(String s)
{
// Stores the frequency of
// 0 and 1 respectively
int []arr = { 0, 0 };
for(char ch : s.toCharArray()) {
arr[ch - '0']++;
}
// Stores most frequent character
char result = arr[0] > arr[1] ? '0' : '1';
// Return Answer
return result;
}
// Function to find a Binary String of
// at most 3N characters having at least
// two of the given three Strings of 2N
// characters as one of its subsequence
static void findStr(String a, String b, String c)
{
// Stores most frequent char
char freq;
// Stores the respective String
// with most frequent values
String s1 = "", s2 = "";
// Code to find the set of
// two Strings with same
// most frequent characters
if (MostFrequent(a) == MostFrequent(b)) {
s1 = a;
s2 = b;
freq = MostFrequent(a);
}
else if (MostFrequent(a) == MostFrequent(c)) {
s1 = a;
s2 = c;
freq = MostFrequent(a);
}
else {
s1 = b;
s2 = c;
freq = MostFrequent(b);
}
// Pointer to iterate Strings
int i = 0, j = 0;
// Traversal using the
// two-pointer approach
while (i < s1.length()&& j < s2.length()) {
// if current character
// is not most frequent
while (i < s1.length() && s1.charAt(i) != freq) {
System.out.print(s1.charAt(i++));
}
// if current character
// is not most frequent
while (j < s2.length() && s2.charAt(j) != freq) {
System.out.print(s2.charAt(j++));
}
// If end of String is reached
if (i == s1.length()|| j == s2.length())
break;
// If both String character
// are same as most frequent
if (s1.charAt(i) == s2.charAt(j)) {
System.out.print(s1.charAt(i));
i++;
j++;
}
else {
System.out.print(s1.charAt(i));
i++;
}
}
// Print leftover characters
// of the String s1
while (i < s1.length()) {
System.out.print(s1.charAt(i++));
}
// Print leftover characters
// of the String s2
while (j < s2.length()) {
System.out.print(s2.charAt(j++));
}
}
// Driver Code
public static void main(String args[])
{
String a = "00";
String b = "11";
String c = "01";
findStr(a, b, c);
}
}
// This code is contributed Saurabh Jaiswal
C#
// C# program for the above approach
using System;
class GFG
{
// Function to find most frequent
// character in the given string
static char MostFrequent(string s)
{
// Stores the frequency of
// 0 and 1 respectively
int []arr = { 0, 0 };
foreach (char ch in s) {
arr[ch - '0']++;
}
// Stores most frequent character
char result = arr[0] > arr[1] ? '0' : '1';
// Return Answer
return result;
}
// Function to find a Binary String of
// at most 3N characters having at least
// two of the given three strings of 2N
// characters as one of its subsequence
static void findStr(string a, string b, string c)
{
// Stores most frequent char
char freq;
// Stores the respective string
// with most frequent values
string s1 = "", s2 = "";
// Code to find the set of
// two strings with same
// most frequent characters
if (MostFrequent(a) == MostFrequent(b)) {
s1 = a;
s2 = b;
freq = MostFrequent(a);
}
else if (MostFrequent(a) == MostFrequent(c)) {
s1 = a;
s2 = c;
freq = MostFrequent(a);
}
else {
s1 = b;
s2 = c;
freq = MostFrequent(b);
}
// Pointer to iterate strings
int i = 0, j = 0;
// Traversal using the
// two-pointer approach
while (i < s1.Length && j < s2.Length) {
// if current character
// is not most frequent
while (i < s1.Length && s1[i] != freq) {
Console.Write(s1[i++]);
}
// if current character
// is not most frequent
while (j < s2.Length && s2[j] != freq) {
Console.Write(s2[j++]);
}
// If end of string is reached
if (i == s1.Length || j == s2.Length)
break;
// If both string character
// are same as most frequent
if (s1[i] == s2[j]) {
Console.Write(s1[i]);
i++;
j++;
}
else {
Console.Write(s1[i]);
i++;
}
}
// Print leftover characters
// of the string s1
while (i < s1.Length) {
Console.Write(s1[i++]);
}
// Print leftover characters
// of the string s2
while (j < s2.Length) {
Console.Write(s2[j++]);
}
}
// Driver Code
public static void Main()
{
string a = "00";
string b = "11";
string c = "01";
findStr(a, b, c);
}
}
// This code is contributed Samim Hossain Mondal.
Python3
# python3 program for the above approach
# Function to find most frequent
# character in the given string
def MostFrequent(s):
# Stores the frequency of
# 0 and 1 respectively
arr = [0, 0]
for ch in s:
arr[ord(ch) - ord('0')] += 1
# Stores most frequent character
result = '0' if arr[0] > arr[1] else '1'
# Return Answer
return result
# Function to find a Binary String of
# at most 3N characters having at least
# two of the given three strings of 2N
# characters as one of its subsequence
def findStr(a, b, c):
# Stores most frequent char
freq = ''
# Stores the respective string
# with most frequent values
s1, s2 = "", ""
# Code to find the set of
# two strings with same
# most frequent characters
if (MostFrequent(a) == MostFrequent(b)):
s1 = a
s2 = b
freq = MostFrequent(a)
elif (MostFrequent(a) == MostFrequent(c)):
s1 = a
s2 = c
freq = MostFrequent(a)
else:
s1 = b
s2 = c
freq = MostFrequent(b)
# Pointer to iterate strings
i, j = 0, 0
# Traversal using the
# two-pointer approach
while (i < len(s1) and j < len(s2)):
# if current character
# is not most frequent
while (i < len(s1) and s1[i] != freq):
print(s1[i], end="")
i += 1
# if current character
# is not most frequent
while (j < len(s2) and s2[j] != freq):
print(s2[j], end="")
j += 1
# If end of string is reached
if (i == len(s1) or j == len(s2)):
break
# If both string character
# are same as most frequent
if (s1[i] == s2[j]):
print(s1[i], end="")
i += 1
j += 1
else:
print(s1[i], end="")
i += 1
# Print leftover characters
# of the string s1
while (i < len(s1)):
print(s1[i], end="")
i += 1
# Print leftover characters
# of the string s2
while (j < len(s2)):
print(s2[j], end="")
j += 1
# Driver Code
if __name__ == "__main__":
a = "00"
b = "11"
c = "01"
findStr(a, b, c)
# This code is contributed by rakeshsahni
Javascript
输出
011
时间复杂度:O(N)
辅助空间:O(N)