Given an array arr[] of size N where each arr[i] is a string denoting an equation, the task is to return true if all the statements are satisfactory otherwise return false if any two equations contradict each other. An equation can be one of the two types below:
- Type 1: “a != b”, which denotes that a is not equal to b
- Type 2: “a == b”, which denotes that both a and b are equal
Note: The provided equations are transitive in nature (i.e. if “a==b” and “b==c“, then “a==c“).
Examples:
Input: N = 3, arr[] = [“a==b”, “a==c”, “b != c”]
Output: False
Explanation: Given “a == b” and “a == c”, using the transitive property we get “b == c “, but arr[2] i.e. “b != c” contradicts that, so we print False.Input: N = 2, arr = [“a == b”, “b == a”]
Output: True
Explanation: Clearly arr[0] and arr[1] are same equations and there does not exists any contradicting equation, hence we print True.
Efficient Approach: Using Disjoint Set Union (DSU) to solve the equations efficiently.
Since the Equations follow the transitive property, we can use Union operation of DSU to put together all the equal equations in a single set, for example if we have {a==b, b==c, d==e} then we will have two sets i.e. {a,b,c} and {d,e} . We can process all the equations of type 2 first using DSU and finally check all the equation of type 1 and retrieve our answer as per the below two cases:
- Case 1: if both the variables of type 1 equation belong to same set
- return False
- Case 2: if all the type1 equation does not follow Case1
- return True
Follow the steps to solve the problem:
- Firstly, initialize the DSU data structure, i.e. Find(), Union(), and parent[] array.
- Make the parent of each character itself.
- For each equation of type 2, merge the variables using the Union operation
- Now for each equation of type 1, if the variables belong to the same disjoint set then return “False” else return “True“.
Below is the implementation of the above algorithm:
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
// parent array to store the parent of // each set of equations int parent[26];
// This function finds the parent of // each disjoint set int find( int v)
{ if (v == parent[v])
return v;
return parent[v] = find(parent[v]);
} // This function is used to merge two // disjoint sets into a single set void Union( int a, int b)
{ a = find(a);
b = find(b);
if (a != b) {
parent[b] = a;
}
} string satisfactoryEquation(vector<string>& arr) { // Loop to initialize the
// parent array
for ( int i = 0; i < 26; i++)
parent[i] = i;
// Iterating on equations of type 2
for ( auto e : arr) {
int a = e[0] - 'a' ;
int b = e[3] - 'a' ;
char c = e[1];
// Equation to find type 2 equation
if (c == '=' ) {
// Merging the variables of
// type 2 equations
Union(a, b);
}
}
// Iterating on equations of type 1
for ( auto e : arr) {
// Condition to check type 1 equation
if (e[1] == '!' ) {
int a = e[0] - 'a' ;
int b = e[3] - 'a' ;
// If parents of both variables
// are same we got
// a contradiction
if (find(a) == find(b))
return "False" ;
}
}
return "True" ;
} // Driver code int main()
{ int N = 3;
vector<string> arr = { "a==b" , "a==c" , "b!=c" };
// Function Call
cout << satisfactoryEquation(arr);
} |
// Java code for the above approach: import java.util.*;
public class Main {
// Parent array to store the parent of
// each set of equations
static int [] parent = new int [ 26 ];
// This function finds the parent of
// each disjoint set
static int find( int v)
{
if (v == parent[v])
return v;
return parent[v] = find(parent[v]);
}
// This function is used to merge two
// disjoint sets into a single set
static void union( int a, int b)
{
a = find(a);
b = find(b);
if (a != b) {
parent[b] = a;
}
}
static String
satisfactoryEquation(ArrayList<String> arr)
{
// Loop to initialize the
// parent array
for ( int i = 0 ; i < 26 ; i++)
parent[i] = i;
// Iterating on equations of type 2
for (String e : arr) {
int a = e.charAt( 0 ) - 'a' ;
int b = e.charAt( 3 ) - 'a' ;
char c = e.charAt( 1 );
// Equation to find type 2 equation
if (c == '=' ) {
// Merging the variables of
// type 2 equations
union(a, b);
}
}
// Iterating on equations of type 1
for (String e : arr) {
// Condition to check type 1 equation
if (e.charAt( 1 ) == '!' ) {
int a = e.charAt( 0 ) - 'a' ;
int b = e.charAt( 3 ) - 'a' ;
// If parents of both variables
// are the same, we got a
// contradiction
if (find(a) == find(b))
return "False" ;
}
}
return "True" ;
}
// Driver code
public static void main(String[] args)
{
int N = 3 ;
ArrayList<String> arr = new ArrayList<String>(
Arrays.asList( "a==b" , "a==c" , "b!=c" ));
// Function Call
System.out.println(satisfactoryEquation(arr));
}
} // This code is contributed by Prasad264 |
# parent array to store the parent of # each set of equations parent = list ( range ( 26 ))
# This function finds the parent of # each disjoint set def find(v):
if v = = parent[v]:
return v
parent[v] = find(parent[v])
return parent[v]
# This function is used to merge two # disjoint sets into a single set def Union(a, b):
a = find(a)
b = find(b)
if a ! = b:
parent[b] = a
def satisfactoryEquation(arr):
# Loop to initialize the parent array
for i in range ( 26 ):
parent[i] = i
# Iterating on equations of type 2
for e in arr:
a = ord (e[ 0 ]) - ord ( 'a' )
b = ord (e[ 3 ]) - ord ( 'a' )
c = e[ 1 ]
# Equation to find type 2 equation
if c = = '=' :
# Merging the variables of type 2 equations
Union(a, b)
# Iterating on equations of type 1
for e in arr:
# Condition to check type 1 equation
if e[ 1 ] = = '!' :
a = ord (e[ 0 ]) - ord ( 'a' )
b = ord (e[ 3 ]) - ord ( 'a' )
# If parents of both variables are same, we got a contradiction
if find(a) = = find(b):
return "False"
return "True"
# Driver code if __name__ = = "__main__" :
N = 3
arr = [ "a==b" , "a==c" , "b!=c" ]
# Function Call
print (satisfactoryEquation(arr))
|
// C# code for the above approach using System;
public class GFG
{ // Parent array to store the parent
// of each set of equations
static int [] parent = new int [26];
// This function finds the parent of
// each disjoint set
static int Find( int v)
{
if (v == parent[v])
return v;
return parent[v] = Find(parent[v]);
}
// This function is used to merge two
// disjoint sets into a single set
static void Union( int a, int b)
{
a = Find(a);
b = Find(b);
if (a != b)
{
parent[b] = a;
}
}
static string SatisfactoryEquation( string [] arr)
{
// Loop to initialize the parent array
for ( int i = 0; i < 26; i++)
{
parent[i] = i;
}
// Iterating on equations of type 2
foreach ( string e in arr)
{
int a = e[0] - 'a' ;
int b = e[3] - 'a' ;
char c = e[1];
// Equation to find type 2 equation
if (c == '=' )
{
// Merging the variables of type 2 equations
Union(a, b);
}
}
// Iterating on equations of type 1
foreach ( string e in arr)
{
// Condition to check type 1 equation
if (e[1] == '!' )
{
int a = e[0] - 'a' ;
int b = e[3] - 'a' ;
// If parents of both variables are
// the same, we have a contradiction
if (Find(a) == Find(b))
{
return "False" ;
}
}
}
return "True" ;
}
// Driver code
public static void Main()
{
string [] arr = { "a==b" , "a==c" , "b!=c" };
// Function Call
Console.WriteLine(SatisfactoryEquation(arr));
}
} |
const parent = {}; function GFG(v) {
if (v === parent[v]) {
return v;
}
return parent[v] = GFG(parent[v]);
} // Function to merge two variables into // single set function union(a, b) {
a = GFG(a);
b = GFG(b);
if (a !== b) {
parent[b] = a;
}
} // Function to determine if the given // equations are satisfactory function satisfactoryEquation(arr) {
// Initialize the parent object
for (let i = 0; i < 26; i++) {
parent[String.fromCharCode( 'a' .charCodeAt(0) + i)] = String.fromCharCode( 'a' .charCodeAt(0) + i);
}
// Iterate through equations of type 2
for (const e of arr) {
const a = e.charCodeAt(0) - 'a' .charCodeAt(0);
const b = e.charCodeAt(3) - 'a' .charCodeAt(0);
const c = e[1];
// Check for type 2 equation
if (c === '=' ) {
// Merge the variables of type 2 equations
union(String.fromCharCode( 'a' .charCodeAt(0) + a), String.fromCharCode( 'a' .charCodeAt(0) + b));
}
}
// Iterate through equations of type 1
for (const e of arr) {
// Check for type 1 equation
if (e[1] === '!' ) {
const a = e.charCodeAt(0) - 'a' .charCodeAt(0);
const b = e.charCodeAt(3) - 'a' .charCodeAt(0);
// If parents of both variables are the same
// we have a contradiction
if (GFG(String.fromCharCode( 'a' .charCodeAt(0) + a)) === GFG(String.fromCharCode( 'a' .charCodeAt(0) + b))) {
return "False" ;
}
}
}
return "True" ;
} // Driver code function main() {
const arr = [ "a==b" , "a==c" , "b!=c" ];
// Function call
console.log(satisfactoryEquation(arr));
} main(); |
False
Time Complexity: O(N), where N is the number of equations
Auxiliary Space: O(26), for the parent array