LeetCode:1202. Smallest String With Swaps交换字符串中的元素(C语言)
发布日期:2021-05-08 18:45:17 浏览次数:17 分类:精选文章

本文共 2152 字,大约阅读时间需要 7 分钟。

为了解决这个问题,我们需要找到一种方法,在给定的字符交换对数组的约束下,生成字典序最小的字符串。通过分析,我们可以发现这些交换对实际上定义了连通块,每个连通块中的字符可以任意排列。因此,我们可以将每个连通块内的字符排序,并将它们放置在相应的位置,从而得到最小的字符串。

方法思路

  • 并查集(Disjoint Set Union, DSU):我们使用并查集来处理交换对,将每个索引归类到其连通块中。每个连通块中的索引可以通过交换对任意排列。
  • 分组字符:根据并查集的结果,将字符串中的每个字符根据其所在的连通块进行分组。
  • 排序字符:对每个连通块中的字符进行排序,并将排序后的字符放置在相应的索引位置,从而得到最小的字符串。
  • 解决代码

    class DSU:    def __init__(self, size):        self.parent = list(range(size))        self.rank = [1] * size    def find(self, x):        if self.parent[x] != x:            self.parent[x] = self.find(self.parent[x])        return self.parent[x]    def union(self, x, y):        x_root = self.find(x)        y_root = self.find(y)        if x_root == y_root:            return        if self.rank[x_root] < self.rank[y_root]:            self.parent[x_root] = y_root        else:            self.parent[y_root] = x_root            if self.rank[x_root] == self.rank[y_root]:                self.rank[x_root] += 1def smallestStringWithSwaps(s, pairs):    n = len(s)    if n == 0:        return s    dsu = DSU(n)    for a, b in pairs:        dsu.union(a, b)    from collections import defaultdict    groups = defaultdict(list)    for i in range(n):        root = dsu.find(i)        groups[root].append(i)    for root in groups:        indices = groups[root]        chars = [s[i] for i in indices]        chars_sorted = sorted(chars)        s_list = list(s)        for i in range(len(indices)):            s_list[indices[i]] = chars_sorted[i]        s = ''.join(s_list)    return s# 读取输入import sysdef main():    s = sys.stdin.readline().strip()    if not s:        print("")        return    pairs = []    while True:        line = sys.stdin.readline()        if not line:            break        line = line.strip()        if not line:            continue        a, b = map(int, line.split(','))        pairs.append( (a, b) )    result = smallestStringWithSwaps(s, pairs)    print(result)if __name__ == "__main__":    main()

    代码解释

  • 并查集类(DSU):用于处理交换对,维护每个索引的父节点和秩。路径压缩和按秩合并确保了高效的操作。
  • 读取输入:从标准输入读取字符串和交换对数组。
  • 处理交换对:使用并查集将每个索引归类到其连通块中。
  • 分组字符:根据每个索引的根节点将字符分组到对应的连通块中。
  • 排序字符:对每个连通块中的字符进行排序,并将排序后的字符放置在相应的索引位置,生成最小的字符串。
  • 通过这种方法,我们能够在允许的交换操作下,高效地生成字典序最小的字符串。

    上一篇:LeetCode:684. Redundant Connection冗余连接(C语言)
    下一篇:LeetCode:228. Summary Ranges汇总区间(C语言)

    发表评论

    最新留言

    逛到本站,mark一下
    [***.202.152.39]2025年04月15日 00时26分19秒