990. 等式方程的可满足性(Satisfiability of Equality Equations)
频次 ★★★ · 难度 🟡 · 高频:阿里
题目
字符串数组 equations,如 "a==b"、"a!=b",判断是否所有等式同时成立。
示例:
输入: ["a==b","b!=a"]
输出: false
输入: ["a==b","b==c","a==c"]
输出: true
思路
并查集 + 两趟扫描:
- 第一趟处理所有
==等式,将两边变量 union - 第二趟检查所有
!=不等式,如果两边的变量在同一集合中则矛盾
代码
public boolean equationsPossible(String[] equations) {
int[] parent = new int[26];
for (int i = 0; i < 26; i++) parent[i] = i;
for (String s : equations) {
if (s.charAt(1) == '=') {
int a = s.charAt(0) - 'a', b = s.charAt(3) - 'a';
union(parent, a, b);
}
}
for (String s : equations) {
if (s.charAt(1) == '!') {
int a = s.charAt(0) - 'a', b = s.charAt(3) - 'a';
if (find(parent, a) == find(parent, b)) return false;
}
}
return true;
}
private int find(int[] parent, int x) {
if (parent[x] != x) parent[x] = find(parent, parent[x]);
return parent[x];
}
private void union(int[] parent, int a, int b) {
parent[find(parent, a)] = find(parent, b);
}复杂度
- 时间:O(n α(26)) ≈ O(n)
- 空间:O(26)
边界条件
- “a!=a”:必然 false(自反性矛盾)
变式
- 684. 冗余连接:图上并查集检测环
- 约束传播:并查集用于判断不等约束的可行性
易错点
- 不能在同一次循环中同时处理 == 和 !=(”=” 还没 union 完就判断 ”!=” 会漏掉传递不等)
- 变量是小写字母,范围 26
- 字符取下标用
s.charAt(0) - 'a'
面试追问
- 如果变量不止 26 个字母呢? 用 HashMap 做并查集,key 为变量名