📜  使两个字符串相同所需的最小对数

📅  最后修改于: 2021-04-22 08:43:21             🧑  作者: Mango

给定两个相同长度的字符串s1s2 ,任务是计算最小字符对(c1,c2) ,以便通过将c1转换为c2或将c2转换为c1在任意字符串中任意次数使两个字符串相同。

例子:

方法:此问题可以通过使用图形或不交集来解决。建立一个空图G并遍历字符串。仅当满足以下条件之一时,才在图形G中添加边:

  • s1 [i]s2 [i]都不在G中。
  • s1 [i]在G中,但s2 [i]在G中。
  • s2 [i]在G中,但s1 [i]在G中。
  • s1 [i]s2 [i]没有路径。

最小对数将是最终图形G中的边数。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function which will check if there is
// a path between a and b by using BFS
bool checkPath(char a, char b, 
           map> &G)
{
    map visited;
    deque queue;
    queue.push_back(a);
    visited[a] = true;
  
    while (!queue.empty()) 
    {
        int n = queue.front();
        queue.pop_front();
  
        if (n == b) return true;
        for (auto i : G[n]) 
        {
            if (visited[i] == false)
            {
                queue.push_back(i);
                visited[i] = true;
            }
        }
    }
    return false;
}
  
// Function to return the 
// minimum number of pairs
int countPairs(string s1, string s2,
         map> &G, int x) 
{
      
    // To store the count of pairs
    int count = 0;
  
    // Iterating through the strings
    for (int i = 0; i < x; i++) 
    {
        char a = s1[i];
        char b = s2[i];
  
        // Check if we can add an edge in the graph
        if (G.find(a) != G.end() and 
            G.find(b) == G.end() and a != b)
        {
            G[a].push_back(b);
            G[b].push_back(a);
            count++;
        }
        else if (G.find(b) != G.end() and
                 G.find(a) == G.end() and a != b) 
        {
            G[b].push_back(a);
            G[a].push_back(b);
            count++;
        } 
        else if (G.find(a) == G.end() and 
                 G.find(b) == G.end() and a != b) 
        {
            G[a].push_back(b);
            G[b].push_back(a);
            count++;
        } 
        else
        {
            if (!checkPath(a, b, G) and a != b)
            {
                G[a].push_back(b);
                G[b].push_back(a);
                count++;
            }
        }
    }
  
    // Return the count of pairs
    return count;
}
  
// Driver Code
int main() 
{
    string s1 = "abb", s2 = "dad";
    int x = s1.length();
    map> G;
    cout << countPairs(s1, s2, G, x) << endl;
  
    return 0;
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of the approach
from collections import defaultdict, deque   
   
# Function which will check if there is 
# a path between a and b by using BFS
def Check_Path(a, b, G):
    visited = defaultdict(bool)
    queue = deque()
    queue.append(a)
    visited[a]= True
    while queue:
        n = queue.popleft()
        if n == b:
            return True
        for i in list(G[n]):
            if visited[i]== False:
                queue.append(i)
                visited[i]= True
    return False
   
# Function to return the minimum number of pairs
def countPairs(s1, s2, G):
    name = defaultdict(bool)
      
    # To store the count of pairs
    count = 0
   
    # Iterating through the strings
    for i in range(x):
        a = s1[i]
        b = s2[i]
   
        # Check if we can add an edge in the graph
        if a in G and b not in G and a != b:
            G[a].append(b)
            G[b].append(a)
            count+= 1
        elif b in G and a not in G and a != b:
            G[b].append(a)
            G[a].append(b)
            count+= 1
        elif a not in G and b not in G and a != b:
            G[a].append(b)
            G[b].append(a)
            count+= 1
        else:
            if not Check_Path(a, b, G) and a != b:
                G[a].append(b)
                G[b].append(a)
                count+= 1
   
    # Return the count of pairs
    return count
   
# Driver code
if __name__=="__main__":
    s1 ="abb"
    s2 ="dad"
    x = len(s1)
    G = defaultdict(list)
    print(countPairs(s1, s2, G))


输出:
2