Skip to content

Commit 1430cda

Browse files
DSU: Satisfiability of Equality Equations
1 parent 135dde3 commit 1430cda

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package Algorithms.DisjointSetUnion;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
/**
8+
* @author Srinivas Vadige, srinivas.vadige@gmail.com
9+
* @since 27 March 2025
10+
*/
11+
public class SatisfiabilityOfEqualityEquations {
12+
public static void main(String[] args) {
13+
String[] equations = {"a==b","b!=c","a==c"};
14+
System.out.println(equationsPossibleMyApproach(equations));
15+
}
16+
17+
static int par[], rank[];
18+
public static boolean equationsPossibleMyApproach(String[] equations) {
19+
par=new int[26];
20+
rank=new int[26];
21+
for (int i=0; i<26; i++) par[i]=i;
22+
23+
// connect all positives
24+
for (String s: equations) {
25+
int a = s.charAt(0)-'a';
26+
int b = s.charAt(3)-'a';
27+
boolean isConnected = s.charAt(1)=='=';
28+
if (isConnected) union(a, b);
29+
}
30+
31+
// check the negative cases if those are true or not
32+
for (String s: equations) {
33+
int a = s.charAt(0)-'a';
34+
int b = s.charAt(3)-'a';
35+
boolean isConnected = s.charAt(1)=='=';
36+
if (!isConnected && isSamePar(a,b)) return false;
37+
38+
}
39+
40+
return true;
41+
}
42+
private static boolean union(int a, int b) {
43+
a=find(a);
44+
b=find(b);
45+
46+
if (a==b) return true;
47+
48+
if(rank[b]<rank[a]) par[b]=a;
49+
else if(rank[a]<rank[b]) par[a]=b;
50+
else{
51+
par[b]=a;
52+
rank[a]++;
53+
}
54+
return false;
55+
}
56+
private static int find(int i) {
57+
while(i!=par[i]) i=par[i];
58+
return i;
59+
}
60+
private static boolean isSamePar(int a, int b) {
61+
return find(a)==find(b);
62+
}
63+
64+
65+
66+
67+
68+
69+
70+
public static boolean equationsPossible2(String[] equations) {
71+
int[] parent = new int[26];
72+
int[] rank = new int[26];
73+
for (int i = 0; i < 26; i++) {
74+
parent[i] = i;
75+
rank[i] = 1;
76+
}
77+
for (String equation : equations) {
78+
if (equation.charAt(1) == '=') {
79+
union(equation.charAt(0) - 'a', equation.charAt(3) - 'a', parent, rank);
80+
}
81+
}
82+
for (String equation : equations) {
83+
if (equation.charAt(1) == '!' && find(equation.charAt(0) - 'a', parent) == find(equation.charAt(3) - 'a', parent)) {
84+
return false;
85+
}
86+
}
87+
return true;
88+
}
89+
90+
public static void union(int x, int y, int[] parent, int[] rank) {
91+
int px = find(x, parent), py = find(y, parent);
92+
if (px == py) return;
93+
if (rank[px] > rank[py]) {
94+
parent[py] = px;
95+
} else if (rank[px] < rank[py]) {
96+
parent[px] = py;
97+
} else {
98+
parent[py] = px;
99+
rank[px] += 1;
100+
}
101+
}
102+
103+
public static int find(int x, int[] parent) {
104+
if (parent[x] == x) return x;
105+
return parent[x] = find(parent[x], parent);
106+
}
107+
108+
109+
110+
111+
112+
113+
114+
115+
public boolean equationsPossible3(String[] strs) {
116+
int[] parent = new int[26]; // rank not needed here
117+
for(int i = 0; i<26; i++) parent[i] = i;
118+
119+
for(String str : strs) {
120+
if(str.charAt(1) == '=') {
121+
int first = str.charAt(0)-'a';
122+
int second = str.charAt(3)-'a';
123+
int p1 = find(first, parent);
124+
int p2 = find(second, parent);
125+
parent[p2] = p1; // UNION
126+
}
127+
}
128+
129+
for(String str : strs) {
130+
if(str.charAt(1) != '=') {
131+
int first = str.charAt(0)-'a';
132+
int second = str.charAt(3)-'a';
133+
int p1 = find(first, parent);
134+
int p2 = find(second, parent);
135+
if(p1 == p2) return false; // IS SAME GROUP
136+
}
137+
}
138+
return true;
139+
}
140+
141+
142+
143+
144+
145+
146+
147+
@SuppressWarnings("unchecked")
148+
public boolean equationsPossibleUsingGraphDFS(String[] equations) {
149+
List<Integer>[] graph = new List[26]; // 2D array
150+
for (int i = 0; i < 26; ++i) graph[i] = new ArrayList<>();
151+
152+
for (String eqn : equations) {
153+
if (eqn.charAt(1) == '=') {
154+
int x = eqn.charAt(0) - 'a';
155+
int y = eqn.charAt(3) - 'a';
156+
graph[x].add(y);
157+
graph[y].add(x);
158+
}
159+
}
160+
161+
int[] color = new int[26];
162+
Arrays.fill(color, -1);
163+
164+
for (int i = 0; i < 26; i++) {
165+
if (color[i] == -1) {
166+
dfs(i, i, color, graph);
167+
}
168+
}
169+
170+
for (String eqn : equations) {
171+
if (eqn.charAt(1) == '!') {
172+
int x = eqn.charAt(0) - 'a';
173+
int y = eqn.charAt(3) - 'a';
174+
if (color[x] == color[y]) // same parent
175+
return false;
176+
}
177+
}
178+
179+
return true;
180+
}
181+
// mark the color of `node` as `c`
182+
// [0:[1,2], 1:[2,3]] --> set color as 0 for 0,1&2, and as we have recursion it'll go inside 1 & it's children and 2 & it's children
183+
// [-1,-1,-1,-1] -> [0,0,0,0]
184+
private static void dfs(int node, int c, int[] color, List<Integer>[] graph) {
185+
if (color[node] == -1) {
186+
color[node] = c;
187+
for (int nei : graph[node])
188+
dfs(nei, c, color, graph);
189+
}
190+
}
191+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ Data Structures And Algorithm Programs
108108
* [Accounts Merge](/Algorithms/DisjointSetUnion/AccountsMerge.java)
109109
* [Number of Operations to Make Network Connected](/Algorithms/DisjointSetUnion/NumberOfOperationsToMakeNetworkConnected.java)
110110
* [Regions Cut By Slashes](/Algorithms/DisjointSetUnion/RegionsCutBySlashes.java)
111+
* [Satisfiability of Equality Equations](/Algorithms/DisjointSetUnion/SatisfiabilityOfEqualityEquations.java)
111112

112113
6. #### [DynamicProgramming](Algorithms/DynamicProgramming/)
113114

0 commit comments

Comments
 (0)