使用并查集算法,核心思想:将 equations
中的算式根据 ==
和 !=
分成两部分,先处理 ==
算式,使得他们通过相等关系各自勾结成门派;然后处理 !=
算式,检查不等关系是否破坏了相等关系的连通性。
/* * @lc app=leetcode.cn id=990 lang=cpp * * [990] 等式方程的可满足性 */ // @lc code=start #include<bits/stdc++.h> using namespace std; class UF { private: int count;//连通的个数 vector<int> parent;//保存节点的父节点 vector<int> size;//保存节点所在连通分量的重量(节点数) public: // 构造函数初始化 UF(int n) { count = n; parent.resize(n); size.resize(n); for(int i = 0; i < n; i++) { parent[i] =i; size[i] = 1; } } // 将节点p 和 节点 q 连通 void Union(int p, int q) { int rootP = find(p); int rootQ = find(q); if(rootP == rootQ) return; if(size[rootP] > size[rootQ]) { parent[rootQ] = rootP; size[rootP] += size[rootQ]; } else { parent[rootP] = rootQ; size[rootQ] += size[rootP]; } count--;//连通个数 -1 } //判断节点p 和 节点 q 是否连通 bool connected(int p, int q) { int rootP = find(p); int rootQ = find(q); return rootP==rootQ; } //返回当前连通个数 int count_num() { return count; } private: // 寻找 x 节点的根节点 int find(int x) { while(parent[x] != x) { //查找根节点的同时,对树进行路径压缩, parent[x] = parent[parent[x]]; x = parent[x]; } return x; } }; class Solution { public: bool equationsPossible(vector<string>& equations) { UF* uf = new UF(26); vector<string> ineuqal; ineuqal.clear(); const int eq_size = equations.size(); for(int i =0;i<eq_size;++i) { string equation = equations[i]; if(equation[1]=='=') { int left_char_index = equation[0]-'a'; int right_char_index = equation[3]-'a'; uf->Union(left_char_index,right_char_index); } else{ ineuqal.push_back(equation); } } const int in_eq_size = ineuqal.size(); for(int j =0;j<in_eq_size;++j) { string ineuqalstr = ineuqal[j]; int left_inequal = ineuqalstr[0]-'a'; int right_inequal = ineuqalstr[3]-'a'; if(uf->connected(left_inequal,right_inequal)){ // delete uf; return false; } } //delete uf; return true; } }; // @lc code=end