根据给定关系替换字符形成的字典最小字符串
给定一个包含N个字符的字符串Str和两个长度相等的字符串S1和S2 ,其中S1[i]和S2[i]相互关联,任务是找到通过替换Str中的字符可以获得的字典最小字符串与他们相关的字符。
例子:
Input: S1 = “rat”, S2 = “cbb”, Str = “trrb”
Output: acca
Explanation: For the given S1 and S2, the characters that are related to each other are (r, c), (a, b), and (t, b).
Hence, in the given string, r can be replaced by c;
b can be replaced by a, and t can be replaced by a.
Hence, Str = “bcca”. Here, b again can be replaced by a.
Therefore, the final value of Str = “acca”, which is the smallest possible.
Input: S1 = “abc”, S2 = “xyz”, Str = “pqr”
Output: pqr
朴素的方法:给定的问题可以通过创建一个无向图来解决,其中连接(x, y)的边表示字符x和y之间的关系。此后,对于给定字符串中的每个字符,使用 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)