📌  相关文章
📜  根据给定关系替换字符形成的字典最小字符串

📅  最后修改于: 2022-05-13 01:57:07.202000             🧑  作者: Mango

根据给定关系替换字符形成的字典最小字符串

给定一个包含N个字符的字符串Str和两个长度相等的字符串S1S2 ,其中S1[i]S2[i]相互关联,任务是找到通过替换Str中的字符可以获得的字典最小字符串与他们相关的字符。

例子:

朴素的方法:给定的问题可以通过创建一个无向图来解决,其中连接(x, y)的边表示字符xy之间的关系。此后,对于给定字符串中的每个字符,使用 DFS 遍历图,并在当前字符的连接顶点中找到最小的字符并替换它们。

时间复杂度: O(N * M),其中 M 代表 S1 或 S2 的大小。
辅助空间: O(M)

高效方法:上述方法可以使用不相交集数据结构来优化解决。这个想法是将所有具有关系的字符分组到同一组中,这可以使用 DSU 有效地完成。这里可以注意到,在 DSU 中并集运算时,应选择节点的父节点作为组中最小的字符,以实现最小的字典顺序。

下面是上述方法的实现:

Python3
# Python code to implement the above approach
 
# Class to implements all functions
# of the Disjoint Set Data Structure
class DisjointSet:
 
    def __init__(self):
        self.size = 26
        self.parent = [i for i in range(self.size)]
        self.chars = [chr(i+97) for i in range(self.size)]
 
    def find_parent(self, x):
        if (self.parent[x] == x):
            return (x)
 
        self.parent[x] = self.find_parent(self.parent[x])
        return (self.parent[x])
 
    def union(self, u, v):
 
        # find parent
        p1 = self.find_parent(u)
        p2 = self.find_parent(v)
 
        # if not same
        if (p1 != p2):
 
            # if p2 smaller than p1
            # then make parent p2
            if (p2 < p1):
                self.parent[p1] = p2
 
            # make parent p1
            else:
                self.parent[p2] = p1
 
# Function to find the lexicographically
# smallest string formed by replacing
# characters according to given relation
def smallestLexStr(S1, S2, Str):
 
    # Create an object of DSU
    ds = DisjointSet()
    M = len(S1)
 
    # Iterate through all given relations
    for i in range(M):
 
            # find ascii value of each character
            # and subtract from ascii value a
            # so that index value between 0-25
        idx1 = ord(S1[i]) - ord('a')
        idx2 = ord(S2[i]) - ord('a')
 
        # take union of both indices
        ds.union(idx1, idx2)
 
    # Convert String into list of characters
    Str = list(Str)
 
    # Iterate through the list of characters
    for i in range(len(Str)):
 
        # Find the smallest character
        # replacement among all relations
        idx = ds.find_parent(ord(Str[i]) - ord('a'))
        Str[i] = ds.chars[idx]
 
    # Convert the list back to a string
    Str = "".join(Str)
 
    # Return Answer
    return Str
 
# Driver Code
if __name__ == "__main__":
    S1 = "rat"
    S2 = "cbb"
    Str = "trrb"
    print(smallestLexStr(S1, S2, Str))


输出
acca

时间复杂度: O(N)
辅助空间: O(1)