Leetcode 3216. Lexicographically Smallest String After a Swap
Given a string s
and a list of pairs of indices in the string pairs
where pairs[i] = [a, b] indicates you can swap the characters at index a
and index b
of the string s
. You can swap the characters at any given index pair any number of times. Return the lexicographically smallest string that s
can be after using the swaps.
s
and the number of pairs pairs
?
s
can have a length up to 100000 and pairs
can have up to 100000 pairs.pairs
?
s
?
s
contains only lowercase English letters.#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;
class UnionFind {
public:
UnionFind(int n): parent(n), rank(n, 0) {
for (int i = 0; i < n; ++i) {
parent[i] = i;
}
}
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]); // path compression
}
return parent[x];
}
void unite(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] < rank[rootY]) {
swap(rootX, rootY);
}
parent[rootY] = rootX;
if (rank[rootX] == rank[rootY]) {
rank[rootX]++;
}
}
}
private:
vector<int> parent;
vector<int> rank;
};
string smallestStringWithSwaps(string s, vector<pair<int, int>>& pairs) {
int n = s.size();
UnionFind uf(n);
// Union step
for (const auto& p : pairs) {
uf.unite(p.first, p.second);
}
// Group all characters by their root index
unordered_map<int, vector<int>> rootToNodes;
for (int i = 0; i < n; ++i) {
int root = uf.find(i);
rootToNodes[root].push_back(i);
}
// Sort each group and place back their characters to the original string
for (auto& entry : rootToNodes) {
vector<int>& indices = entry.second;
string temp;
for (int index : indices) {
temp += s[index];
}
sort(temp.begin(), temp.end());
sort(indices.begin(), indices.end());
for (int i = 0; i < indices.size(); ++i) {
s[indices[i]] = temp[i];
}
}
return s;
}
Thus, the overall time complexity of the solution is O(n log n).
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?