Back to all solutions
#1202 - Smallest String With Swaps
Problem Description
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.
Solution
/**
* @param {string} s
* @param {number[][]} pairs
* @return {string}
*/
var smallestStringWithSwaps = function(s, pairs) {
const parent = Array.from({ length: s.length }, (_, i) => i);
const rank = new Array(s.length).fill(0);
function find(x) {
if (parent[x] !== x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
pairs.forEach(([x, y]) => union(x, y));
const components = new Map();
for (let i = 0; i < s.length; i++) {
const root = find(i);
if (!components.has(root)) {
components.set(root, { indices: [], chars: [] });
}
components.get(root).indices.push(i);
components.get(root).chars.push(s[i]);
}
const result = new Array(s.length);
for (const { indices, chars } of components.values()) {
chars.sort((a, b) => b.localeCompare(a));
indices.sort((a, b) => a - b);
indices.forEach((idx, i) => result[idx] = chars.pop());
}
return result.join('');
function union(x, y) {
const rootX = find(x);
const rootY = find(y);
if (rootX !== rootY) {
if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
};