Skip to content

Latest commit

 

History

History
94 lines (75 loc) · 2.5 KB

1202. 交换字符串中的元素-Medium.md

File metadata and controls

94 lines (75 loc) · 2.5 KB

给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。

你可以 任意多次交换 在 pairs 中任意一对索引处的字符。

返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。

 

示例 1:

输入s = "dcab", pairs = [[0,3],[1,2]]
输出"bacd"
解释交换 s[0]  s[3], s = "bcad"
交换 s[1]  s[2], s = "bacd"

示例 2:

输入s = "dcab", pairs = [[0,3],[1,2],[0,2]]
输出"abcd"
解释交换 s[0]  s[3], s = "bcad"
交换 s[0]  s[2], s = "acbd"
交换 s[1]  s[2], s = "abcd"

示例 3:

输入s = "cba", pairs = [[0,1],[1,2]]
输出"abc"
解释交换 s[0]  s[1], s = "bca"
交换 s[1]  s[2], s = "bac"
交换 s[0]  s[1], s = "abc"

提示:

  • 1 <= s.length <= 10^5
  • 0 <= pairs.length <= 10^5
  • 0 <= pairs[i][0], pairs[i][1] < s.length
  • s 中只含有小写英文字母

Solution

  • 主要思路是使用并查集,将可以互换位置的元素聚类
  • 对每个类内部的元素进行排序,并按从小到大放回这些元素之前占位的index处
  • 注意:并查集中路径压缩的小技巧
class UnionFind:
    def __init__(self, s):
        self.father = {i:i for i in range(len(s))}
        
    def find(self, x):
        root = x
        
        while self.father[root] != root:
            root = self.father[root]
        
        # 路径压缩
        while x != root:
            original_father = self.father[x]
            self.father[x] = root
            x = original_father
        
        return root
    
    def merge(self, x, y):
        root_x,root_y = self.find(x),self.find(y)
        
        if root_x != root_y:
            self.father[root_x] = root_y

class Solution:
    def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
        uf = UnionFind(s)

        for x, y in pairs:
            uf.merge(x, y)

        connected_components = collections.defaultdict(list)
        for node in range(len(s)):
            connected_components[uf.find(node)].append(node)

        res = list(s)
        for v in connected_components.values():
            tmp = [s[i] for i in v]
            if len(v) > 1:
                tmp.sort()
            for i in range(len(v)):
                res[v[i]] = tmp[i]
        return ''.join(res)