smallest-string-with-swaps py3

This commit is contained in:
Sangeeth Sudheer 2022-04-28 01:16:10 +05:30
parent ce4608aa34
commit 39191b4421
2 changed files with 94 additions and 0 deletions

View File

@ -0,0 +1,42 @@
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 1:**
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"
**Example 2:**
Input: s = "dcab", pairs = [[0,3],[1,2],[0,2]]
Output: "abcd"
Explaination:
Swap s[0] and s[3], s = "bcad"
Swap s[0] and s[2], s = "acbd"
Swap s[1] and s[2], s = "abcd"
**Example 3:**
Input: s = "cba", pairs = [[0,1],[1,2]]
Output: "abc"
Explaination:
Swap s[0] and s[1], s = "bca"
Swap s[1] and s[2], s = "bac"
Swap s[0] and s[1], s = "abc"
**Constraints:**
* `1 <= s.length <= 10^5`
* `0 <= pairs.length <= 10^5`
* `0 <= pairs[i][0], pairs[i][1] < s.length`
* `s` only contains lower case English letters.
https://leetcode.com/problems/smallest-string-with-swaps

View 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)