這一題利用並查集(可以高效的回答連接類的問題)來解決
首先遍歷所有的等式,構造並查集。同一個等式中的兩個變量屬於同一個連通分量,因此將兩個變量進行合併。
然後遍歷所有的不等式。同一個不等式中的兩個變量不能屬於同一個連通分量,因此對兩個變量分別查找其所在的連通分量,如果兩個變量在同一個連通分量中,則產生矛盾,返回 false。
如果遍歷完所有的不等式沒有發現矛盾,則返回 true。
class UnionFind{
private:
vector<int> save;
public:
UnionFind(){
save.resize(26);
iota(save.begin() , save.end(), 0); //自增的賦值
}
int find( int index ){
if( index == save[index] ) return index; //等於本身的話,證明爲根節點
else{ //沿着當前變量父節點一直向上查找
save[index] = find( save[index] );
return save[index];
}
}
void union_elements( int index1, int index2 ){
save[ find(index1) ] = find(index2);
}
};
class Solution {
public:
bool equationsPossible(vector<string>& equations) {
UnionFind uf;
for(const string& str : equations){
if(str[1] == '='){
int index1 = str[0] - 'a';
int index2 = str[3] - 'a';
uf.union_elements(index1,index2);
}
}
for(const string& str : equations){
if(str[1] == '!'){
int index1 = str[0] - 'a';
int index2 = str[3] - 'a';
if(uf.find(index1) == uf.find(index2))
return false;
}
}
return true;
}
};