Formatted question description: https://leetcode.ca/all/990.html

# 990. Satisfiability of Equality Equations (Medium)

Given an array equations of strings that represent relationships between variables, each string equations[i] has length 4 and takes one of two different forms: "a==b" or "a!=b".  Here, a and b are lowercase letters (not necessarily different) that represent one-letter variable names.

Return true if and only if it is possible to assign integers to variable names so as to satisfy all the given equations.

Example 1:

Input: ["a==b","b!=a"]
Output: false
Explanation: If we assign say, a = 1 and b = 1, then the first equation is satisfied, but not the second.  There is no way to assign the variables to satisfy both equations.


Example 2:

Input: ["b==a","a==b"]
Output: true
Explanation: We could assign a = 1 and b = 1 to satisfy both equations.


Example 3:

Input: ["a==b","b==c","a==c"]
Output: true


Example 4:

Input: ["a==b","b!=c","c==a"]
Output: false


Example 5:

Input: ["c==c","b==d","x!=z"]
Output: true


Note:

1. 1 <= equations.length <= 500
2. equations[i].length == 4
3. equations[i] and equations[i] are lowercase letters
4. equations[i] is either '=' or '!'
5. equations[i] is '='

Related Topics:
Union Find, Graph

## Solution 1. Union Find

// OJ: https://leetcode.com/problems/satisfiability-of-equality-equations/

// Time: O(N)
// Space: O(1)
class UnionFind {
unordered_map<char, char> id;
unordered_map<char, int> rank;
public:
void connect(char a, char b) {
int x = find(a), y = find(b);
if (x == y) return;
if (rank[x] <= rank[y]) {
id[x] = y;
if (rank[x] == rank[y]) rank[y]++;
} else id[y] = x;
}
char find(char a) {
if (!id.count(a)) {
rank[a] = 1;
id[a] = a;
}
return id[a] == a ? a : (id[a] = find(id[a]));
}
};
class Solution {
public:
bool equationsPossible(vector<string>& equations) {
UnionFind uf;
for (auto e : equations) {
if (e == '=') uf.connect(e, e);
}
for (auto e : equations) {
if (e == '!' && uf.find(e) == uf.find(e)) return false;
}
return true;
}
};


## Solution 2. Union Find

// OJ: https://leetcode.com/problems/satisfiability-of-equality-equations/

// Time: O(N)
// Space: O(1)
class Solution {
int uf;
int find(int x) {
return uf[x] == x ? x : (uf[x] = find(uf[x]));
}
public:
bool equationsPossible(vector<string>& equations) {
for (int i = 0; i < 26; ++i) uf[i] = i;
for (auto e : equations) {
if (e == '=') uf[find(e - 'a')] = find(e - 'a');
}
for (auto e : equations) {
if (e == '!' && find(e - 'a') == find(e - 'a')) return false;
}
return true;
}
};


## Solution 3. Graph Coloring (DFS)

// OJ: https://leetcode.com/problems/satisfiability-of-equality-equations/

// Time: O(N)
// Space: O(N)
class Solution {
vector<bool> visited = vector<bool>(26, false);
int color;
void dfs(int u, int c) {
visited[u] = true;
color[u] = c;
for (auto v : adj[u]) {
if (!visited[v]) dfs(v, c);
}
}
public:
bool equationsPossible(vector<string>& equations) {
for (auto e : equations) {
if (e != '=') continue;
}
for (int i = 0, c = 0; i < 26; ++i) {
if (!visited[i]) dfs(i, c++);
}
for (auto e : equations) {
if (e == '!' && color[e - 'a'] == color[e - 'a']) return false;
}
return true;
}
};


Java

class Solution {
public boolean equationsPossible(String[] equations) {
Map<Character, Set<Character>> equalMap = new HashMap<Character, Set<Character>>();
Map<Character, Set<Character>> unequalMap = new HashMap<Character, Set<Character>>();
for (String equation : equations) {
char var1 = equation.charAt(0), var2 = equation.charAt(3);
if (equation.charAt(1) == '=') {
Set<Character> equalSet1 = equalMap.getOrDefault(var1, new HashSet<Character>());
Set<Character> equalSet2 = equalMap.getOrDefault(var2, new HashSet<Character>());
for (char var : equalSet1)
equalMap.put(var, equalSet1);
for (char var : equalSet2)
equalMap.put(var, equalSet2);
} else if (var1 == var2)
return false;
}
for (String equation : equations) {
if (equation.charAt(1) == '!') {
char var1 = equation.charAt(0), var2 = equation.charAt(3);
Set<Character> equalSet = equalMap.getOrDefault(var1, new HashSet<Character>());
if (equalSet.contains(var2))
return false;
}
}
return true;
}
}