Skip to content

Commit d7bf1be

Browse files
authored
Create smallest-string-with-swaps.cpp
1 parent bd6267c commit d7bf1be

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

C++/smallest-string-with-swaps.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Time: O(nlogn)
2+
// Space: O(n)
3+
4+
class Solution {
5+
public:
6+
string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) {
7+
UnionFind union_find(s.length());
8+
for (const auto& pair : pairs) {
9+
union_find.union_set(pair[0], pair[1]);
10+
}
11+
unordered_map<int, vector<char>> components;
12+
for (int i = 0; i < s.length(); ++i) {
13+
components[union_find.find_set(i)].emplace_back(s[i]);
14+
}
15+
for (auto& [i, list] : components) {
16+
sort(list.begin(), list.end(), greater<char>());
17+
}
18+
for (int i = 0; i < s.length(); ++i) {
19+
const auto& j = union_find.find_set(i);
20+
s[i] = components[j].back();
21+
components[j].pop_back();
22+
}
23+
return s;
24+
}
25+
26+
private:
27+
class UnionFind {
28+
public:
29+
UnionFind(const int n) : set_(n) {
30+
iota(set_.begin(), set_.end(), 0);
31+
}
32+
33+
int find_set(const int x) {
34+
if (set_[x] != x) {
35+
set_[x] = find_set(set_[x]); // Path compression.
36+
}
37+
return set_[x];
38+
}
39+
40+
bool union_set(const int x, const int y) {
41+
int x_root = find_set(x), y_root = find_set(y);
42+
if (x_root == y_root) {
43+
return false;
44+
}
45+
set_[min(x_root, y_root)] = max(x_root, y_root);
46+
return true;
47+
}
48+
49+
private:
50+
vector<int> set_;
51+
};
52+
};
53+
54+
// Time: O(nlogn)
55+
// Space: O(n)
56+
class Solution2 {
57+
public:
58+
string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) {
59+
unordered_map<int, vector<int>> adj;
60+
for (const auto& pair : pairs) {
61+
adj[pair[0]].emplace_back(pair[1]);
62+
adj[pair[1]].emplace_back(pair[0]);
63+
}
64+
unordered_set<int> lookup;
65+
string result = s;
66+
for (int i = 0; i < s.length(); ++i) {
67+
if (lookup.count(i)) {
68+
continue;
69+
}
70+
vector<int> component;
71+
dfs(i, adj, &lookup, &component);
72+
sort(component.begin(), component.end());
73+
vector<char> chars;
74+
for (const auto& k : component) {
75+
chars.emplace_back(result[k]);
76+
}
77+
sort(chars.begin(), chars.end());
78+
for (int j = 0; j < component.size(); ++j) {
79+
result[component[j]] = chars[j];
80+
}
81+
}
82+
return result;
83+
}
84+
85+
private:
86+
void dfs(int i, const unordered_map<int, vector<int>>& adj,
87+
unordered_set<int> *lookup, vector<int> *component) {
88+
lookup->emplace(i);
89+
component->emplace_back(i);
90+
if (!adj.count(i)) {
91+
return;
92+
}
93+
for (const auto& j : adj.at(i)) {
94+
if (lookup->count(j)) {
95+
continue;
96+
}
97+
dfs(j, adj, lookup, component);
98+
}
99+
}
100+
};

0 commit comments

Comments
 (0)