LeetCode 990. Satisfiability of Equality Equations
given an array of equations and nonequations, check if all the equations are true. if any of them is false then return false;
Input: [“a==b”,“b!=a”]
Output: false
remember: we will only contains == and != operator.
idea:
这种题目要用图的思想去想:
由于具有传递姓,比如ab and ca, 那么自然而然就有bc, 我们可以把所有的相等的 连成一个图 然后如果有不等的 那么就重新开一个图。这些图都是无向图。
在构建这些图的过程中 如果我们发现有一个节点 同时属于两个确定分离的图 这样的话就一定返回false
如果一直构建到最后 并没有出现任何问题 那么就返回true.
因为我们只需要把相等的节点聚集在一起即可 然后需要找的时候快速查找就行 因此不需要hashmap 只用hashset就行了
但是有个问题,比如我们先把ab放进去 创造了一个图 然后把cd放进去,一看之前的set不能加 又创造了一个图,这时候我们默认有两个set了 但是如果第三个等式是ac 这个时候 如果按照之前的想法 检查到这两个节点位于两个不同的图中(set中)那就直接返回false了 可是实际情况是 我们这个时候要将这两个set合并。(虽然说set合并也没什么 但是终归不算是常规操作 而且还涉及到删除被合并的那个set会造成for loop的混乱)
所以重新调整一下思路,对于所有的\ 我们都可以看做是构建图。对于所有的!=都可以看作是检验。
所以我们先处理所有的\==部分 然后再处理!=部分。
在图的构建过程中 因为我们选用的是hashset,所以不可避免地
当两者都是旧的时候:当两个节点分别属于不同的图的时候 需要对两个set进行合并。对被合并的那个进行删除
当属于同一个图的时候 不需要进行处理
当两者都是新的 就新建一个图(set)把这两者放进去
当两者有一个是新的 就把这个新的归到旧的所属的图中。
下面是我自己implement的 但是属实垃圾 写了50行代码却没有完成一个简单的功能
class Solution {
public boolean equationsPossible(String[] equations) {
if (equations == null || equation.length <= 1) return true;
List<HashSet<Character>> list = new ArrayList<>();
for(String equation: equations) {
char n1 = equation.charAt(0);
char n2 = equation.charAt(3);
char sign = equation.charAt(1);
if (sign == '=') {
//first we need to check if those node are new or old
int numOld = 0;
boolean sameSet = true;
int[] index new int[]{-1, -1};
int k = 0;
for (int i = 0; i < list.size(); i++) {
Hashset<Character> set = list.get(i);
if (set.contains(n1) && set.contains(n2)) {
//do nothing
break;
} else (set.contains(n1) || set.contains(n2)) {
numOld++;
sameSet = false;
index[k++] = i;
}
}
if (numOld == 2) {
if (sameSet) {
//do nothing
} else {
list.get(index[0]).addAll(list.get(index[1]));
list.remove(index[1]);
//merge
//but we need index of those two set to locate them and merge and delete
}
} else if (numOld == 0) {
HashSet<Character> set = new HashSet<>();
set.add(n1);
set.add(n2);
list.add(set);
} else {
//we also need the index of that old node's set index, just to put the new node in this set
list.get(index[0]).add(n1);
list.get(index[0]).add(n2); //we don't know which one is the new one, so we add them all
}
}
}
for (String equation: equations) {
char n1 = equation.charAt(0);
char n2 = equation.charAt(3);
char sign = equation.charAt(1);
if (sign == '!') {
int numOld = 0;
}
}
}
}
这就是自己垃圾思路和代码的最好体现。
重新整理一下思路
仔细想一下 这个东西不就是并查集嘛 就是一堆东西 然后找是不是属于同一个图中。
再仔细想一下 我们为什么要发明并查集?就是为了解决这个问题的。
看看其他人怎么写的
这思路是如此清晰 让人感觉十分惭愧
class Solution {
public boolean equationsPossible(String[] equations) {
//maximum 26 letters--26 nodes
int[] uf = new int[26];
for (int i = 0; i < 26; i++) {
uf[i] = i;
}
//we use all the == equations to construxt this union find
for (String e:equations) {
if (e.charAt(1) == '=') {
uf[find(uf, e.charAt(0) - 'a')] = find(uf, e.charAt(3) - 'a');
//uf(parent of first node) = parent of second node
//and this equation actually means that the the first node and second node are in the same graph
}
}
for (String e: equations) {
if (e.charAt(1) == '!') {
if (find(uf, e.charAt(0) - 'a') == find(uf, e.charAt(3) - 'a')) {
return false; //if those two nodes are from different graph
}
}
}
return true;
}
private int find(int[] uf, int x) {//the root of x is find(x)
if (x != uf[x]) { //until we can't o further, this is the parent node, otherwise let's keeps digging
uf[x] = find(uf, uf[x]); //
}
return uf[x];
}
}

浙公网安备 33010602011771号