1. 程式人生 > 其它 >力扣 leetcode 1202. 交換字串中的元素 (python)

力扣 leetcode 1202. 交換字串中的元素 (python)

技術標籤:pythonleetcode字串python演算法leetcode資料結構

Topic:

給你一個字串 s,以及該字串中的一些「索引對」陣列 pairs,其中 pairs[i] = [a, b] 表示字串中的兩個索引(編號從 0 開始)。
你可以 任意多次交換 在 pairs 中任意一對索引處的字元。
返回在經過若干次交換後,s 可以變成的按字典序最小的字串。

Example_1:

輸入:s = “dcab”, pairs = [[0,3],[1,2]]
輸出:“bacd”
解釋:
交換 s[0] 和 s[3], s = “bcad”
交換 s[1] 和 s[2], s = “bacd”

Example_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”

Example_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”

Solution:

本題整體思路基於

並查集模板實現
首先是建圖的過程:
將s中的值按照索引模擬成圖的n個節點
每個索引是一個節點
之後通過pairs中的陣列
將對應的可以互換的節點連通起來

之後是尋找聯通的所有節點用於儲存連通圖
將根節點相同的放在一起
以根節點作為鍵
值為陣列,儲存以該根節點為根的並查集中所有節點下標

最後分別對每個根節點對應的連通關係按照字典序進行單獨排列
將排序好的結果整合到res中即可完成

Code:

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 = collections.defaultdict(list) for node in range(len(s)): connected[uf.find(node)].append(node) # 重新賦值 res = list(s) for nodes in connected.values(): last = nodes string = sorted(res[d] for d in nodes) for e, f in zip(last,string): res[e] = f return "".join(res)

Result:
在這裡插入圖片描述