📌  相关文章
📜  通过从两个字符串反转相等长度的子字符串来检查两个字符串是否可以相等

📅  最后修改于: 2021-04-26 09:20:29             🧑  作者: Mango

给定两个字符串S1S2 ,任务是通过从相等长度的两个字符串中颠倒子字符串来检查是否可以使字符串S1等于字符串S2
注意:子字符串可以反转任意多次。
例子:

方法:

  1. 这个想法是通过对两个字符串进行排序来使两个字符串相等。
  2. 首先,检查两个字符串是否具有相同的字符集。如果不是,则答案为“否”。
  3. 将子字符串的长度固定为2。现在,这意味着交换相邻字符。
  4. 现在,进行排序通过反转大小2的或在其它字子串,交换相邻字符的字符串所需的移动次数,是字符串的反转次数。
  5. 如果两个字符串的反转计数相同,则答案为“是”。
  6. 如果它们具有不同的反转计数,则只有在满足以下条件中的至少一项时,才可以使它们相等:
    • 首先,如果反转计数的奇偶性相同,即偶数或奇数,则答案为“是”。我们将继续交换已排序字符串中的任意一对元素,直到另一对元素被排序为止。由于反转计数的差异将是偶数,因此两次交换任何对都不会产生任何变化。
    • 第二,如果奇偶校验是不一样的,则必须有至少与任何所述字符串的频率大于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 frequnecy
    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 frequnecy
    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 frequnecy
    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 frequnecy
    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


输出:
Yes


时间复杂度:

O(N)

空间复杂度:

O(1)