文章目录
- 题目一:1061. 按字典序排列最小的等效字符串
- 题目二:990. 等式方程的可满足性
题目一:1061. 按字典序排列最小的等效字符串
1061. 按字典序排列最小的等效字符串
并查集使用整数,字符自然和整数有一个映射,ASCII
码!
我们按问题来看并不要按秩合并,因为最终我们需要找到字典序最小的等价字符串,我们只需要让每一个字符找到最小的等价字符即可(因为是按一个字符等价的)。我们尽可能的用ASCII
小的作为父亲,这样也可以迅速找倒字典序最小的等价字符。
26
个小写字母,只需要26
个整数即可映射!
class UnionFind{
public:
UnionFind(int n){
for(int i = 0;i < n; ++ i){
fa.emplace_back(i);
}
}
int Find(int x){
return fa[x] == x ? x : (fa[x] = Find(fa[x]));
}
void Union(int x, int y){
int fax = Find(x);
int fay = Find(y);
if(fax < fay){
fa[fay] = fax;
}else fa[fax] = fay;
return;
}
private:
vector<int> fa;
};
class Solution {
public:
string smallestEquivalentString(string s1, string s2, string baseStr) {
UnionFind uf(26);
for(int i = 0; i < s1.size(); ++ i){
uf.Union(s1[i] - 'a', s2[i] - 'a');
}
for(auto & ch : baseStr){
ch = uf.Find(ch - 'a') + 'a';
}
return baseStr;
}
};
题目二:990. 等式方程的可满足性
990. 等式方程的可满足性
如果将每个字符当做图中的一个顶点,则有a == b
,可以认为a
和b
之间存在一条边,由于这是一个等价关系具有传递性,因此一个连通分量中的所有字符都是等价的。
这里和之前不同的是,不等于不能在第一次遍历的时候就进行判断,因为此时的等价关系还并不完备。
因此,我们第一遍构造等价关系;第二遍进行判断即可。
class UnionFind{
public:
UnionFind(int n){
for(int i = 0;i < n; ++ i){
fa.emplace_back(i);
rank.emplace_back(1);
}
}
int Find(int x){
return fa[x] == x ? x : (fa[x] = Find(fa[x]));
}
void Union(int x, int y){
int fax = Find(x);
int fay = Find(y);
if(fax != fay){
if(rank[fax] > rank[fay]){
fa[fay] = fax;
rank[fax] ++;
}else{
fa[fax] = fay;
rank[fay] ++;
}
}
return;
}
private:
vector<int> fa;
vector<int> rank;
};
class Solution {
public:
bool equationsPossible(vector<string>& equations) {
UnionFind uf(26);
for(int i = 0;i < equations.size(); ++ i){
int c1 = equations[i][0] - 'a';
int c2 = equations[i][3] - 'a';
if(equations[i][1] == '=') uf.Union(c1,c2);
}
for(int i = 0;i < equations.size(); ++ i){
int c1 = equations[i][0] - 'a';
int c2 = equations[i][3] - 'a';
if(equations[i][1] == '!')
if(uf.Find(c1) == uf.Find(c2)) return false;
}
return true;
}
};