1202. 交换字符串中的元素
难度中等257收藏分享切换为英文接收动态反馈
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。
你可以 任意多次交换 在 pairs 中任意一对索引处的字符。
返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。
示例 1:
输入: s = "dcab", pairs = [[0,3],[1,2]]
输出: "bacd"
解释:
交换 s[0] 和 s[3], s = "bcad"
交换 s[1] 和 s[2], s = "bacd"
示例 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"
示例 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"
解题:
class UnionFind {
constructor(length) {
this.parent = new Array(length).fill(0).map((v, j) => j);
console.log(this.parent);
this.rank = new Array(length).fill(1);
this.setCount = length;
}
findSet(index) {
if (this.parent[index] !== index) {
this.parent[index] = this.findSet(this.parent[index]);
}
return this.parent[index];
}
unite(indei, index2) {
let root1 = this.findSet(indei),
root2 = this.findSet(index2);
if (root1 !== root2) {
if (this.rank[root1] < this.rank[root2]) {
[root1, root2] = [root2, root1];
}
this.parent[root2] = root1;
this.rank[root1] += this.rank[root2];
this.setCount--;
}
}
getCount() {
return this.setCount;
}
}
var smallestStringWithSwaps = function (s, pairs) {
const len = s.length;
let uf = new UnionFind(len);
for (const iterator of pairs) {
const [key1, key2] = iterator;
if (uf.findSet(key1) !== uf.findSet(key2)) {
uf.unite(key1, key2);
}
}
const fa = uf.parent;
let vec = new Array(len).fill(0).map(() => new Array());
for (let i = 0; i < len; i++) {
fa[i] = uf.findSet(i);
vec[fa[i]].push(s[i]);
}
vec = vec.map((v) => {
if (v.length > 0) {
return v.sort((a, b) => a.charCodeAt() - b.charCodeAt());
}
return v;
});
let p = new Array(len).fill(0);
let ans = new Array(len).fill("1");
for (let i = 0; i < len; i++) {
ans[i]=vec[fa[i]][p[fa[i]]]
p[fa[i]]++
}
return ans.join("")
};
console.log(
smallestStringWithSwaps("dcab", [
[0, 3],
[1, 2],
])
);