Problem
You are given an array of strings equations
that represent relationships between variables where each string equations[i]
is of length 4
and takes one of two different forms: "xi==yi"
or "xi!=yi"
.Here, xi
and yi
are lowercase letters (not necessarily different) that represent one-letter variable names.
Return true
if it is possible to assign integers to variable names so as to satisfy all the given equations, or false
otherwise.
Examples
Example 1:
Input: equations = ["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: equations = ["b==a","a==b"]
Output: true
Explanation: We could assign a = 1 and b = 1 to satisfy both equations.
Constraints
1 <= equations.length <= 500
equations[i].length == 4
equations[i][0]
is a lowercase letter.equations[i][1]
is either'='
or'!'
.equations[i][2]
is'='
.equations[i][3]
is a lowercase letter.
Solution
Method 1 - Using Hashmap for Storing Relations ❌
The code provided below will not work for the example ["a==b", "b!=c", "c==a"]
.
Code
public boolean equationsPossible(String[] equations) {
Map<Character, Set<Character>> eqm = new HashMap<>();
Map<Character, Set<Character>> neqm = new HashMap<>();
for (String equation: equations) {
char x = equation.charAt(0);
char y = equation.charAt(3);
Map<Character, Set<Character>> mapToCheck = new HashMap<>();
Map<Character, Set<Character>> mapToAdd = new HashMap<>();
if (equation.charAt(1) == '=') {
mapToCheck = neqm;
mapToAdd = eqm;
}else {
mapToCheck = eqm;
mapToAdd = neqm;
}
if (mapToCheck.containsKey(x) && mapToCheck.get(x).contains(y)) {
return false;
}
mapToAdd.putIfAbsent(x, new HashSet<>());
mapToAdd.putIfAbsent(y, new HashSet<>());
mapToAdd.get(x).add(y);
mapToAdd.get(y).add(x);
}
return true;
}
Complexity
- Time:
O(n)
- Space:
O(n)
Method 2 - Using Union Find
Considering the example ["a==b", "b!=c", "c==a"]
, a
and b
belong to the same set. However, b
and c
should not be in the same set. Therefore, when trying to place c
and a
in the same set, it causes a contradiction since b
and c
cannot coexist in the same set. We can address this using code similar to Disjoint Set - Weighted Union Implementation.
Code
class Solution {
int[] parent = new int[26];
int[] size = new int[26];
public boolean equationsPossible(String[] equations) {
for (int i = 0; i<26; i++) {
size[i] = 1;
parent[i] = i;
}
for (String s: equations) {
if (s.charAt(1) == '=') {
int a = s.charAt(0) - 'a';
int b = s.charAt(3) - 'a';
union(a, b);
}
}
for (String s: equations) {
if (s.charAt(1) == '!') {
int a = s.charAt(0) - 'a';
int b = s.charAt(3) - 'a';
if (isConnected(a, b)) {
return false;
}
}
}
return true;
}
public void union(int a, int b) {
int roota = find(a);
int rootb = find(b);
if (roota == rootb) {
return;
}
if (size[roota] >= size[rootb]) {
parent[rootb] = roota;
size[roota] += size[rootb];
} else {
parent[roota] = rootb;
size[rootb] += size[roota];
}
}
public int find(int a) {
while (parent[a] != a) {
a = parent[a];
}
return a;
}
public boolean isConnected(int a, int b) {
int roota = find(a);
int rootb = find(b);
if (roota == rootb) {
return true;
}
return false;
}
}
Complexity
- Time:
O(N)
- Space:
O(N)