题目
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。
你可以 任意多次交换 在 pairs 中任意一对索引处的字符。
返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。
链接:https://leetcode.com/problems/smallest-string-with-swaps/
You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string.
You can swap the characters at any pair of indices in the given pairs any number of times.
Return the lexicographically smallest string that s can be changed to after using the swaps.
Example:
Input: s = “dcab”, pairs = [[0,3],[1,2]]
Output: “bacd”
Explaination:
Swap s[0] and s[3], s = “bcad”
Swap s[1] and s[2], s = “bacd”
思路及代码
并查集
- 将所有可以互换的元素放在同一个集合中,每个集合分别排序,再插入回原来的序列中
- 并查集是遍历所有边(pair),使所有属于同一个集合的点拥有同一个root
class Solution:
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
# 寻根
def root(node):
if p[node] != node:
p[node] = root(p[node])
return p[node]
# p记录根
p = list(range(len(s)))
for x, y in pairs:
px, py = root(x), root(y)
if px != py:
p[px] = py
# pdict将所有根作为key,属于这个根的所有元素作为value
pdict = collections.defaultdict(list)
for i in range(len(p)):
pdict[root(p[i])].append(s[i])
# 将各集合中元素进行排序
for key in pdict:
pdict[key].sort(reverse=True)
# root(i)可以找到当前位置在p中对应的根节点
# pdict[root(i)]是该根节点对应的所有value
# pop()可以输出当前集合排序最靠前的元素(因为之前sort(reverse=True)了)
ans = []
for i in range(len(s)):
ans.append(pdict[root(i)].pop())
return "".join(ans)
DFS
class Solution:
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
g = [[] for i in range(len(s))]
seen = [0] * len(s)
idx = []
tmp = []
ans = [0] * len(s)
# g存储邻接表
for i,j in pairs:
g[i].append(j)
g[j].append(i)
# 用dfs找到所有可以相互转换的元素的集合
def dfs(node):
if seen[node]:
return
seen[node] = 1
idx.append(node)
tmp.append(s[node])
for nxt in g[node]:
dfs(nxt)
for i in range(len(s)):
if seen[i]:
continue
dfs(i)
idx.sort()
tmp.sort()
# idx记录集合中原有的index
# tmp记录集合中原有的元素
# 两者都sort然后分别插入应有的位置即可
for j in range(len(idx)):
ans[idx[j]] = tmp[j]
idx = []
tmp = []
return "".join(ans)
复杂度
Union-Find:
T
=
O
(
n
l
o
g
n
+
V
+
E
)
T = O(nlogn + V + E)
T=O(nlogn+V+E)
DFS:
T
=
O
(
n
l
o
g
n
+
k
∗
(
V
+
E
)
)
T = O(nlogn + k*(V+E))
T=O(nlogn+k∗(V+E))
S
=
O
(
n
)
S = O(n)
S=O(n)