smallest-string-with-swaps py3
This commit is contained in:
52
1308_smallest-string-with-swaps/python3/solution.py
Normal file
52
1308_smallest-string-with-swaps/python3/solution.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from collections import defaultdict
|
||||
|
||||
class Solution:
|
||||
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
|
||||
'''
|
||||
Key idea: if (a, b) indexes can be swapped and (b, c) indexes can
|
||||
be swapped, then (a, c) can be swapped so infinite swap across (a, b, c).
|
||||
Can be expanded to cover any other letters that are swappable.
|
||||
'''
|
||||
|
||||
# Make the adjacency list
|
||||
swapmap = defaultdict(list)
|
||||
|
||||
for i, j in pairs:
|
||||
swapmap[i].append(j)
|
||||
swapmap[j].append(i)
|
||||
|
||||
|
||||
def dfs(s, vertex, chars, vertices):
|
||||
chars.append(s[vertex])
|
||||
vertices.append(vertex)
|
||||
|
||||
visited.add(vertex)
|
||||
|
||||
for neighbor in swapmap[vertex]:
|
||||
if neighbor not in visited:
|
||||
dfs(s, neighbor, chars, vertices)
|
||||
|
||||
|
||||
output = [''] * len(s)
|
||||
visited = set()
|
||||
|
||||
for vertex, _ in enumerate(s):
|
||||
if vertex not in visited:
|
||||
connected_chars = []
|
||||
connected_vertices = []
|
||||
|
||||
dfs(s, vertex, connected_chars, connected_vertices)
|
||||
|
||||
# This might seem confusing but remember that if we find one character
|
||||
# with the `vertex` connected (i.e swappable) with other characters, then
|
||||
# they can all be swapped with each other infinite times. Our goal is to
|
||||
# get the lexicographically smallest string (i.e most sorted) from doing
|
||||
# these allowed swaps. Hence, we can go ahead and safely sort the chars
|
||||
# obtained from DFS of vertex.
|
||||
connected_chars.sort()
|
||||
connected_vertices.sort()
|
||||
|
||||
for i, connected_vertex in enumerate(connected_vertices):
|
||||
output[connected_vertex] = connected_chars[i]
|
||||
|
||||
return ''.join(output)
|
||||
Reference in New Issue
Block a user