990. 等式方程的可满足性
题目:
思路:
【1】并交集的方式
由于是只有26个小写字母,所以可以用int数组来表示
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
这就表示每个字母当前的指向父节点都会自己,值为 字符-'a'的值(如'a' - 'a' = 0)
对应字符串的变化
1)字符串:c==c (这种本身就是这样指向的,故不变)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
2)字符串:f==b
所以 先找 f 的父节点 5, b 的父节点 1
然后 parent[5] = 1; 合并父节点 ,那么就会出现 5->1 和 1->1
[0, 1, 2, 3, 4, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
3)字符串:b==c
所以 先找 b 的父节点 1, c 的父节点 2
然后 parent[1] = 2; 合并父节点 ,那么就会出现 2->2 和 1->2
汇总的话就是 5->1,1->2,2->2
[0, 2, 2, 3, 4, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
4)字符串:f==z
所以 先找z 的父节点 25 , f 的父节点 1 指向b,再由1找到 2 指向c(所以f变更指向直接指向c,省略b的指向)
[0, 2, 25, 3, 4, 2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
代码展示:
//时间0 ms 击败 100% //内存39.5 MB 击败 87.17% class Solution { // 查并交集的情况 public boolean equationsPossible(String[] equations) { int[] parent = new int[26]; // 首先设置每个节点的父节点都是自己 for (int i = 0; i < 26; i++) { parent[i] = i; } // 先是处理相等的情况 for (String str : equations) { if (str.charAt(1) == '=') { // 取出他们当前的节点 int index1 = str.charAt(0) - 'a'; int index2 = str.charAt(3) - 'a'; // 合并两者的节点的父节点 union(parent, index1, index2); } } // 再处理相等的情况 for (String str : equations) { if (str.charAt(1) == '!') { int index1 = str.charAt(0) - 'a'; int index2 = str.charAt(3) - 'a'; // 分别查找两者的父节点,看看是否相同 if (find(parent, index1) == find(parent, index2)) { return false; } } } return true; } public void union(int[] parent, int index1, int index2) { parent[find(parent, index1)] = find(parent, index2); } // 这里是核心的查找父节点的逻辑 public int find(int[] parent, int index) { while (parent[index] != index) { // 这一步并不关键,因为他的主要作用是将层级差巨大的进行缩短 // 如 f->b->c ,直接变为 f->c,这种形式,用于缩短查找,但没有也不影响结果 parent[index] = parent[parent[index]]; index = parent[index]; } return index; } }