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:
1
2
3
4
5
6
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:
1
2
3
4
5
6
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"
If a set of indices are connected by swap pairs, the characters at those indices can be freely rearranged among themselves. For example, in the string:
1
2
"sdcrqbpa"
[[0,3],[4,6],[3,4],[1,7],[2,5],[5,7]]
there are two groups of interconnected indices, so we can rearrange the characters within each group to achieve the lexicographically smallest string.
#include<vector>#include<string>#include<queue>#include<unordered_map>usingnamespace std;
classSolution {
public: string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) {
int n = s.size();
vector<int> p(n);
for (int i =0; i < n; ++i) p[i] = i;
function<int(int)> find = [&](int x) { return p[x] == x ? x : p[x] = find(p[x]); };
for (auto& e : pairs) {
int a = find(e[0]), b = find(e[1]);
if (a != b) p[b] = a;
}
unordered_map<int, priority_queue<char, vector<char>, greater<char>>> mp;
for (int i =0; i < n; ++i) mp[find(i)].push(s[i]);
string res;
for (int i =0; i < n; ++i) res += mp[find(i)].top(), mp[find(i)].pop();
return res;
}
};
import java.util.*;
classSolution {
public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
int n = s.length();
int[] p =newint[n];
for (int i = 0; i < n; i++) p[i]= i;
for (List<Integer> edge : pairs) {
int a = find(p, edge.get(0)), b = find(p, edge.get(1));
if (a != b) p[b]= a;
}
Map<Integer, PriorityQueue<Character>> mp =new HashMap<>();
for (int i = 0; i < n; i++) {
int root = find(p, i);
mp.computeIfAbsent(root, k ->new PriorityQueue<>());
mp.get(root).add(s.charAt(i));
}
StringBuilder sb =new StringBuilder();
for (int i = 0; i < n; i++) {
int root = find(p, i);
sb.append(mp.get(root).poll());
}
return sb.toString();
}
privateintfind(int[] p, int x) {
if (p[x]!= x) p[x]= find(p, p[x]);
return p[x];
}
}
import java.util.*
classSolution {
funsmallestStringWithSwaps(s: String, pairs: List<List<Int>>): String {
val n = s.length
val p = IntArray(n) { it }
funfind(x: Int): Int { if (p[x] != x) p[x] = find(p[x]); return p[x] }
for (e in pairs) {
val a = find(e[0]); val b = find(e[1])
if (a != b) p[b] = a
}
val mp = mutableMapOf<Int, PriorityQueue<Char>>()
for (i in0 until n) {
val root = find(i)
mp.computeIfAbsent(root) { PriorityQueue() }.add(s[i])
}
val sb = StringBuilder()
for (i in0 until n) {
val root = find(i)
sb.append(mp[root]!!.poll())
}
return sb.toString()
}
}
import heapq
classSolution:
defsmallestStringWithSwaps(self, s: str, pairs: list[list[int]]) -> str:
n = len(s)
p = list(range(n))
deffind(x):
if p[x] != x: p[x] = find(p[x])
return p[x]
for a, b in pairs:
pa, pb = find(a), find(b)
if pa != pb: p[pb] = pa
mp = {}
for i, ch in enumerate(s):
root = find(i)
if root notin mp: mp[root] = []
heapq.heappush(mp[root], ch)
res = []
for i in range(n):
root = find(i)
res.append(heapq.heappop(mp[root]))
return''.join(res)
use std::collections::{HashMap, BinaryHeap};
use std::cmp::Reverse;
impl Solution {
pubfnsmallest_string_with_swaps(s: String, pairs: Vec<Vec<i32>>) -> String {
let n = s.len();
letmut p: Vec<usize>= (0..n).collect();
fnfind(p: &mut Vec<usize>, x: usize) -> usize {
if p[x] != x { p[x] = find(p, p[x]); } p[x]
}
for e in&pairs {
let a = find(&mut p, e[0] asusize);
let b = find(&mut p, e[1] asusize);
if a != b { p[b] = a; }
}
letmut mp: HashMap<usize, BinaryHeap<Reverse<u8>>>= HashMap::new();
let s_bytes = s.as_bytes();
for i in0..n {
let root = find(&mut p, i);
mp.entry(root).or_default().push(Reverse(s_bytes[i]));
}
letmut res =vec![0u8; n];
for i in0..n {
let root = find(&mut p, i);
res[i] = mp.get_mut(&root).unwrap().pop().unwrap().0;
}
String::from_utf8(res).unwrap()
}
}