给定两个字符串S1和S2 ,任务是检查是否可以通过从两个相等长度的字符串中反转子字符串来使字符串S1等于字符串S2 。
注意:一个子串可以反转任意次。
例子:
Input: S1 = “abbca”, S2 = “acabb”
Output: Yes
Explanation:
The string S1 and S2 can be made equal by:
Reverse S1 in the range [2, 4] (length = 3), S1 = “abacb”
Reverse S2 in the range [1, 3] (length = 3), S2 = “abacb”
S1 = “abacb” and S2 = “abacb”, after reversing.
Hence, both can be made equal.
Input: “S1 = “abcd”, S2 = “abdc”
Output: No
方法:
- 这个想法是通过对它们进行排序来使两个字符串相等。
- 首先,检查两个字符串是否具有相同的字符集。如果不是,那么答案是“否”。
- 将 substring 的长度固定为 reverse 为 2。现在,这意味着交换相邻字符。
- 现在,进行排序通过反转大小2的或者换句话说子串,交换相邻字符的字符串所需的移动次数,是字符串的反转次数。
- 如果两个字符串具有相同的反转计数,则答案为“是”。
- 如果它们具有不同的反转计数,则只有在至少满足以下条件之一时才能使它们相等:
- 首先,如果反转计数的奇偶性相同,即偶数或奇数,则答案为“是”。我们将继续交换排序字符串中的任何一对元素,直到另一个元素被排序。由于反转计数的差异将是偶数,因此将任何对交换两次不会产生任何变化。
- 第二,如果奇偶校验是不一样的,则必须有至少与任何所述字符串的频率大于1的一个字符。我们只会交换它们,直到另一个被排序。由于交换相同的字符不会做任何改变。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// function to count inversion
// count of the string
int inversionCount(string& s)
{
// for storing frequency
int freq[26] = { 0 };
int inv = 0;
for (int i = 0; i < s.length(); i++) {
int temp = 0;
// Add all the characters which
// are less than the ith character
// before i.
for (int j = 0; j < int(s[i] - 'a'); j++)
// adding the count to inversion
// count
temp += freq[j];
inv += (i - temp);
// updating the character in
// the frequency array
freq[s[i] - 'a']++;
}
return inv;
}
// function to check whether any
// of the string have a repeated
// character
bool haveRepeated(string& S1,
string& S2)
{
int freq[26] = { 0 };
for (char i : S1) {
if (freq[i - 'a'] > 0)
return true;
freq[i - 'a']++;
}
for (int i = 0; i < 26; i++)
freq[i] = 0;
for (char i : S2) {
if (freq[i - 'a'] > 0)
return true;
freq[i - 'a']++;
}
return false;
}
// function to check whether the
// string S1 and S2 can be made
// equal by reversing sub strings
// of same size in both strings
void checkToMakeEqual(string S1,
string S2)
{
// frequency array to check
// whether both string have
// same character or not
int freq[26] = { 0 };
for (int i = 0; i < S1.length(); i++) {
// adding the frequency;
freq[S1[i] - 'a']++;
}
bool flag = 0;
for (int i = 0; i < S2.length(); i++) {
if (freq[S2[i] - 'a'] == 0) {
// if the character is not in S1
flag = true;
break;
}
// decrementing the frequency
freq[S2[i] - 'a']--;
}
if (flag == true) {
// If both string doesnot
// have same characters or not
cout << "No\n";
return;
}
// finding inversion count
// of both strings
int invCount1 = inversionCount(S1);
int invCount2 = inversionCount(S2);
if (invCount1 == invCount2
|| (invCount1 & 1) == (invCount2 & 1)
|| haveRepeated(S1, S2)) {
// If inversion count is same,
// or have same parity or if
// any of the string have a
// repeated character then
// the answer is Yes else No
cout << "Yes\n";
}
else
cout << "No\n";
}
// driver code
int main()
{
string S1 = "abbca", S2 = "acabb";
checkToMakeEqual(S1, S2);
return 0;
}
Python3
# Python3 program for the above approach
# function to count inversion
# count of the string
def inversionCount(s):
# for storing frequency
freq = [0 for _ in range(26)]
inv = 0
for i in range(len(s)):
# we'll add all the characters
# which are less than the ith
# character before i.
temp = 0
for j in range(ord(s[i]) - ord('a')):
# adding the count to
# inversion count
temp += freq[j]
inv += (i - temp)
# updating the character in
# the frequency array
freq[ord(s[i]) - ord('a')] += 1
return inv
# function to check whether
# any of the string have a
# repeated character
def haveRepeated(S1, S2):
freq = [0 for _ in range(26)]
for i in range(len(S1)):
if freq[ord(S1[i]) - ord('a')] > 0:
return 1
freq[ord(S1[i]) - ord('a')] += 1
for i in range(26):
freq[i] = 0
for i in range(len(S2)):
if freq[ord(S2[i]) - ord('a')] > 0:
return 1
freq[ord(S2[i]) - ord('a')] += 1
return 0
# function to check whether
# the string S1 and S2 can
# be made equal by reversing
# sub strings ofsame size in
# both strings
def checkToMakeEqual(S1, S2):
# frequency array to check
# whether both string have
# same character or not
freq = [0 for _ in range(26)]
for i in range(len(S1)):
# adding the frequency;
freq[ord(S1[i]) - ord('a')] += 1
flag = 0
for i in range(len(S2)):
if freq[ord(S2[i]) - ord('a')] == 0:
# if the character is not in S1
flag = 1
break
# decrementing the frequency
freq[ord(S2[i]) - ord('a')] -= 1
if flag == 1:
# If both string does not
# have same characters or not
print("No")
return
# finding inversion count of
# both strings
invCount1 = inversionCount(S1)
invCount2 = inversionCount(S2)
if ((invCount1 == invCount2) or
((invCount1 % 2) == (invCount2 % 2)) or
haveRepeated(S1, S2) == 1):
# If inversion count is same,
# or have same parity
# or if any of the string
# have a repeated character
# then the answer is Yes else No
print("Yes")
else:
print("No")
# Driver Code
S1 = "abbca"
S2 = "acabb"
checkToMakeEqual(S1, S2)
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG{
// Function to count inversion
// count of the string
static int inversionCount(String s)
{
// For storing frequency
int[] freq = new int[26];
int inv = 0;
for(int i = 0; i < s.length(); i++)
{
int temp = 0;
// Add all the characters which
// are less than the ith character
// before i.
for(int j = 0;
j < (int)(s.charAt(i) - 'a');
j++)
// Adding the count to inversion
// count
temp += freq[j];
inv += (i - temp);
// Updating the character in
// the frequency array
freq[s.charAt(i) - 'a']++;
}
return inv;
}
// Function to check whether any
// of the string have a repeated
// character
static boolean haveRepeated(String S1,
String S2)
{
int[] freq = new int[26];
for(char i : S1.toCharArray())
{
if (freq[i - 'a'] > 0)
return true;
freq[i - 'a']++;
}
for(int i = 0; i < 26; i++)
freq[i] = 0;
for(char i : S2.toCharArray())
{
if (freq[i - 'a'] > 0)
return true;
freq[i - 'a']++;
}
return false;
}
// Function to check whether the
// string S1 and S2 can be made
// equal by reversing sub strings
// of same size in both strings
static void checkToMakeEqual(String S1,
String S2)
{
// Frequency array to check
// whether both string have
// same character or not
int[] freq = new int[26];
for(int i = 0; i < S1.length(); i++)
{
// Adding the frequency;
freq[S1.charAt(i) - 'a']++;
}
boolean flag = false;
for(int i = 0; i < S2.length(); i++)
{
if (freq[S2.charAt(i) - 'a'] == 0)
{
// If the character is not in S1
flag = true;
break;
}
// Decrementing the frequency
freq[S2.charAt(i) - 'a']--;
}
if (flag == true)
{
// If both string doesnot
// have same characters or not
System.out.println("No");
return;
}
// Finding inversion count
// of both strings
int invCount1 = inversionCount(S1);
int invCount2 = inversionCount(S2);
if (invCount1 == invCount2 ||
(invCount1 & 1) == (invCount2 & 1) ||
haveRepeated(S1, S2))
{
// If inversion count is same,
// or have same parity or if
// any of the string have a
// repeated character then
// the answer is Yes else No
System.out.println("Yes");
}
else
System.out.println("No");
}
// Driver Code
public static void main (String[] args)
{
String S1 = "abbca", S2 = "acabb";
checkToMakeEqual(S1, S2);
}
}
// This code is contributed by offbeat
C#
// C# program for the above approach
using System;
class GFG{
// Function to count inversion
// count of the string
static int inversionCount(String s)
{
// For storing frequency
int[] freq = new int[26];
int inv = 0;
for(int i = 0; i < s.Length; i++)
{
int temp = 0;
// Add all the characters which
// are less than the ith character
// before i.
for(int j = 0;
j < (int)(s[i] - 'a');
j++)
// Adding the count to inversion
// count
temp += freq[j];
inv += (i - temp);
// Updating the character in
// the frequency array
freq[s[i] - 'a']++;
}
return inv;
}
// Function to check whether any
// of the string have a repeated
// character
static bool haveRepeated(String S1,
String S2)
{
int[] freq = new int[26];
foreach(char i in S1.ToCharArray())
{
if (freq[i - 'a'] > 0)
return true;
freq[i - 'a']++;
}
for(int i = 0; i < 26; i++)
freq[i] = 0;
foreach(char i in S2.ToCharArray())
{
if (freq[i - 'a'] > 0)
return true;
freq[i - 'a']++;
}
return false;
}
// Function to check whether the
// string S1 and S2 can be made
// equal by reversing sub strings
// of same size in both strings
static void checkToMakeEqual(String S1,
String S2)
{
// Frequency array to check
// whether both string have
// same character or not
int[] freq = new int[26];
for(int i = 0; i < S1.Length; i++)
{
// Adding the frequency;
freq[S1[i] - 'a']++;
}
bool flag = false;
for(int i = 0; i < S2.Length; i++)
{
if (freq[S2[i] - 'a'] == 0)
{
// If the character is not in S1
flag = true;
break;
}
// Decrementing the frequency
freq[S2[i] - 'a']--;
}
if (flag == true)
{
// If both string doesnot
// have same characters or not
Console.WriteLine("No");
return;
}
// Finding inversion count
// of both strings
int invCount1 = inversionCount(S1);
int invCount2 = inversionCount(S2);
if (invCount1 == invCount2 ||
(invCount1 & 1) == (invCount2 & 1) ||
haveRepeated(S1, S2))
{
// If inversion count is same,
// or have same parity or if
// any of the string have a
// repeated character then
// the answer is Yes else No
Console.WriteLine("Yes");
}
else
Console.WriteLine("No");
}
// Driver Code
public static void Main(String[] args)
{
String S1 = "abbca", S2 = "acabb";
checkToMakeEqual(S1, S2);
}
}
// This code is contributed by gauravrajput1
Javascript
输出:
Yes
时间复杂度:
空间复杂度: