Count of distinct groups of strings formed after performing equivalent operation
Last Updated :
17 Feb, 2023
Given an array arr[] of N strings consisting of lowercase alphabets, the task is to find the number of distinct groups of strings formed after performing the equivalent operation.
Two strings are said to be equivalent if there exists the same character in both the strings and if there exists another string that is equivalent to one of the strings in the group of equivalent string then that string is also equivalent to that group.
Examples:
Input: arr[] = {"a", "b", "ab", "d"}
Output: 2
Explanation:
As strings "b" and "ab" have 'b' as the same character, they are equivalent also "ab" and the string"a" have 'a' as the same character, so the strings "a", "b", "ab" are equivalent and "d" is another string.
Therefore, the count of distinct group of strings formed is 2.
Input: arr[] = {"ab", "bc", "abc"}
Output: 1
Approach: The given problem can be solved using the Disjoint Set Union, the idea is to traverse the string and mark all the characters of the current string as true and perform the union operation on the first character of the current string with the character 'a', and count the different number of parents in the parent vector and store it. Follow the below steps to solve the problem:
- Initialize the vectors parent(27), rank(27, 0), total(26, false), and current(26, false).
- Initialize a variable, say distCount as 0 that stores the count of distinct strings.
- Iterate over the range [0, 27) using the variable i and set the value of parent[i] as i.
- Iterate over the range [0, N) using the variable i and perform the following steps:
- Iterate over the range [0, 26) using the variable j and set current[j] to false.
- Iterate over the characters of the string arr[i] using the variable ch and set current[ch - 'a'] to true.
- Iterate over the range [0, 26) using the variable j and if current[j] is true then set total[j] to true and call for the function Union(parent, rank, arr[i][0] - 'a', j).
- Iterate over the range [0, 26) using the variable i and check if total[i] is true and Find(parent, i) is I if it is true then increment the value of distCount by 1.
- Finally, print the value of distCount.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to perform the find operation
// to find the parent of a disjoint set
int Find(vector<int>& parent, int a)
{
return parent[a]
= (parent[a] == a ? a : Find(parent, parent[a]));
}
// Function to perform union operation
// of disjoint set union
void Union(vector<int>& parent,
vector<int>& rank, int a,
int b)
{
// Find the parent of node a and b
a = Find(parent, a);
b = Find(parent, b);
// Update the rank
if (rank[a] == rank[b])
rank[a]++;
if (rank[a] > rank[b])
parent[b] = a;
else
parent[a] = b;
}
// Function to find the number of distinct
// strings after performing the
// given operations
void numOfDistinctStrings(string arr[],
int N)
{
// Stores the parent elements
// of the sets
vector<int> parent(27);
// Stores the rank of the sets
vector<int> rank(27, 0);
for (int j = 0; j < 27; j++) {
// Update parent[i] to i
parent[j] = j;
}
// Stores the total characters
// traversed through the strings
vector<bool> total(26, false);
// Stores the current characters
// traversed through a string
vector<bool> current(26, false);
for (int i = 0; i < N; i++) {
for (int j = 0; j < 26; j++) {
// Update current[i] to false
current[j] = false;
}
for (char ch : arr[i]) {
// Update current[ch - 'a'] to true
current[ch - 'a'] = true;
}
for (int j = 0; j < 26; j++) {
// Check if current[j] is true
if (current[j]) {
// Update total[j] to true
total[j] = true;
// Add arr[i][0] - 'a' and
// j elements to same set
Union(parent, rank,
arr[i][0] - 'a', j);
}
}
}
// Stores the count of distinct strings
int distCount = 0;
for (int i = 0; i < 26; i++) {
// Check total[i] is true and
// parent of i is i only
if (total[i] && Find(parent, i) == i) {
// Increment the value of
// distCount by 1
distCount++;
}
}
// Print the value of distCount
cout << distCount << endl;
}
// Driver Code
int main()
{
string arr[] = { "a", "ab", "b", "d" };
int N = sizeof(arr) / sizeof(arr[0]);
numOfDistinctStrings(arr, N);
return 0;
}
Java
import java.util.*;
public class Main {
// Function to perform the find operation
// to find the parent of a disjoint set
static int Find(int[] parent, int a) {
return parent[a] = (parent[a] == a ? a : Find(parent, parent[a]));
}
// Function to perform union operation
// of disjoint set union
static void Union(int[] parent, int[] rank, int a, int b) {
// Find the parent of node a and b
a = Find(parent, a);
b = Find(parent, b);
// Update the rank
if (rank[a] == rank[b])
rank[a]++;
if (rank[a] > rank[b])
parent[b] = a;
else
parent[a] = b;
}
// Function to find the number of distinct
// strings after performing the
// given operations
static void numOfDistinctStrings(String[] arr, int N) {
// Stores the parent elements
// of the sets
int[] parent = new int[27];
// Stores the rank of the sets
int[] rank = new int[27];
for (int j = 0; j < 27; j++) {
// Update parent[i] to i
parent[j] = j;
}
// Stores the total characters
// traversed through the strings
boolean[] total = new boolean[26];
// Stores the current characters
// traversed through a string
boolean[] current = new boolean[26];
for (int i = 0; i < N; i++) {
for (int j = 0; j < 26; j++) {
// Update current[i] to false
current[j] = false;
}
for (char ch : arr[i].toCharArray()) {
// Update current[ch - 'a'] to true
current[ch - 'a'] = true;
}
for (int j = 0; j < 26; j++) {
// Check if current[j] is true
if (current[j]) {
// Update total[j] to true
total[j] = true;
// Add arr[i].charAt(0) - 'a' and
// j elements to same set
Union(parent, rank,
arr[i].charAt(0) - 'a', j);
}
}
}
// Stores the count of distinct strings
int distCount = 0;
for (int i = 0; i < 26; i++) {
// Check total[i] is true and
// parent of i is i only
if (total[i] && Find(parent, i) == i) {
// Increment the value of
// distCount by 1
distCount++;
}
}
// Print the value of distCount
System.out.println(distCount);
}
// Driver Code
public static void main(String[] args) {
String[] arr = { "a", "ab", "b", "d" };
int N = arr.length;
numOfDistinctStrings(arr, N);
}
}
Python3
# python program for the above approach
# Function to perform the find operation
# to find the parent of a disjoint set
def Find(parent, a):
if parent[a] == a:
parent[a] = a
return parent[a]
else:
parent[a] = Find(parent, parent[a])
return parent[a]
# Function to perform union operation
# of disjoint set union
def Union(parent, rank, a, b):
# Find the parent of node a and b
a = Find(parent, a)
b = Find(parent, b)
# Update the rank
if (rank[a] == rank[b]):
rank[a] += 1
if (rank[a] > rank[b]):
parent[b] = a
else:
parent[a] = b
# Function to find the number of distinct
# strings after performing the
# given operations
def numOfDistinctStrings(arr, N):
# Stores the parent elements
# of the sets
parent = [0 for _ in range(27)]
# Stores the rank of the sets
rank = [0 for _ in range(27)]
for j in range(0, 27):
# Update parent[i] to i
parent[j] = j
# Stores the total characters
# traversed through the strings
total = [False for _ in range(26)]
# Stores the current characters
# traversed through a string
current = [False for _ in range(26)]
for i in range(0, N):
for j in range(0, 26):
# Update current[i] to false
current[j] = False
for ch in arr[i]:
# Update current[ch - 'a'] to true
current[ord(ch) - ord('a')] = True
for j in range(0, 26):
# Check if current[j] is true
if (current[j]):
# Update total[j] to true
total[j] = True
# Add arr[i][0] - 'a' and
# j elements to same set
Union(parent, rank, ord(arr[i][0]) - ord('a'), j)
# Stores the count of distinct strings
distCount = 0
for i in range(0, 26):
# Check total[i] is true and
# parent of i is i only
if (total[i] and Find(parent, i) == i):
# Increment the value of
# distCount by 1
distCount += 1
# Print the value of distCount
print(distCount)
# Driver Code
if __name__ == "__main__":
arr = ["a", "ab", "b", "d"]
N = len(arr)
numOfDistinctStrings(arr, N)
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
class GFG {
// Function to perform the find operation
// to find the parent of a disjoint set
static int Find(int[] parent, int a)
{
return parent[a]
= (parent[a] == a ? a
: Find(parent, parent[a]));
}
// Function to perform union operation
// of disjoint set union
static void Union(int[] parent, int[] rank, int a,
int b)
{
// Find the parent of node a and b
a = Find(parent, a);
b = Find(parent, b);
// Update the rank
if (rank[a] == rank[b])
rank[a]++;
if (rank[a] > rank[b])
parent[b] = a;
else
parent[a] = b;
}
// Function to find the number of distinct
// strings after performing the
// given operations
static void numOfDistinctStrings(string[] arr, int N)
{
// Stores the parent elements
// of the sets
int[] parent = new int[(27)];
// Stores the rank of the sets
int[] rank = new int[(27)];
for (int j = 0; j < 27; j++) {
// Update parent[i] to i
parent[j] = j;
}
// Stores the total characters
// traversed through the strings
bool[] total = new bool[26];
// Stores the current characters
// traversed through a string
bool[] current = new bool[26];
for (int i = 0; i < N; i++) {
for (int j = 0; j < 26; j++) {
// Update current[i] to false
current[j] = false;
}
foreach(char ch in arr[i])
{
// Update current[ch - 'a'] to true
current[ch - 'a'] = true;
}
for (int j = 0; j < 26; j++) {
// Check if current[j] is true
if (current[j]) {
// Update total[j] to true
total[j] = true;
// Add arr[i][0] - 'a' and
// j elements to same set
Union(parent, rank, arr[i][0] - 'a', j);
}
}
}
// Stores the count of distinct strings
int distCount = 0;
for (int i = 0; i < 26; i++) {
// Check total[i] is true and
// parent of i is i only
if (total[i] && Find(parent, i) == i) {
// Increment the value of
// distCount by 1
distCount++;
}
}
// Print the value of distCount
Console.WriteLine(distCount);
}
// Driver Code
public static void Main()
{
string[] arr = { "a", "ab", "b", "d" };
int N = arr.Length;
numOfDistinctStrings(arr, N);
}
}
// This code is contributed by ukasp.
JavaScript
// Function to perform the find operation
// to find the parent of a disjoint set
function Find(parent, a) {
if (parent[a] == a) {
parent[a] = a;
return parent[a];
} else {
parent[a] = Find(parent, parent[a]);
return parent[a];
}
}
// Function to perform union operation
// of disjoint set union
function Union(parent, rank, a, b) {
// Find the parent of node a and b
a = Find(parent, a);
b = Find(parent, b);
// Update the rank
if (rank[a] == rank[b]) {
rank[a] += 1;
}
if (rank[a] > rank[b]) {
parent[b] = a;
} else {
parent[a] = b;
}
}
// Function to find the number of distinct
// strings after performing the
// given operations
function numOfDistinctStrings(arr, N) {
// Stores the parent elements
// of the sets
let parent = new Array(27).fill(0);
// Stores the rank of the sets
let rank = new Array(27).fill(0);
for (let j = 0; j < 27; j++) {
// Update parent[i] to i
parent[j] = j;
}
// Stores the total characters
// traversed through the strings
let total = new Array(26).fill(false);
// Stores the current characters
// traversed through a string
let current = new Array(26).fill(false);
for (let i = 0; i < N; i++) {
for (let j = 0; j < 26; j++) {
// Update current[i] to false
current[j] = false;
}
for (let k = 0; k < arr[i].length; k++) {
let ch = arr[i][k];
// Update current[ch - 'a'] to true
current[ch.charCodeAt(0) - 'a'.charCodeAt(0)] = true;
}
for (let j = 0; j < 26; j++) {
// Check if current[j] is true
if (current[j]) {
// Update total[j] to true
total[j] = true;
// Add arr[i][0] - 'a' and
// j elements to same set
Union(parent, rank, arr[i].charCodeAt(0) - 'a'.charCodeAt(0), j);
}
}
}
// Stores the count of distinct strings
let distCount = 0;
for (let i = 0; i < 26; i++) {
// Check total[i] is true and
// parent of i is i only
if (total[i] && Find(parent, i) == i) {
// Increment the value of
// distCount by 1
distCount += 1;
}
}
// Print the value of distCount
console.log(distCount);
}
// Driver Code
let arr = ["a", "ab", "b", "d"];
let N = arr.length;
numOfDistinctStrings(arr, N);
// This code is contributed by lokeshpotta20.
Time Complexity: O(N*log N), as we are using a loop to traverse N times and Union function will cost us logN time.
Auxiliary Space: O(1), as we are using a constant space of size 27.
Similar Reads
Count of distinct possible strings after performing given operations
Given a numeric string S consisting of only three types of characters 0, 1, and 2 initially and following two operations: The occurrence of two consecutive 1 can be replaced by 3.The occurrence of two consecutive 2 can be replaced by 4.The given task is to find the total number of different strings
10 min read
Count of distinct strings that can be obtained after performing exactly one swap
Given a string s containing lowercase English alphabet characters. The task is to calculate the number of distinct strings that can be obtained after performing exactly one swap. Input: s = "geek"Output: 6Explanation: Following are the strings formed by doing exactly one swapstrings = ["egek","eegk"
5 min read
Count Number of Distinct Binary Strings After Applying Flip Operations
Given a binary string s and a positive integer k. In a operation you can repeatedly choose any substring of length k in s and flip all its characters (0s to 1s, 1s to 0s). The task is to return the number of distinct strings that can be obtained, modulo 10^9 + 7. You can perform the flip operation a
5 min read
Count number of distinct substrings of a given length
Given a string S of length N consisting of lower-case English alphabets and an integer 'l', find the number of distinct substrings of length 'l' of the given string. Examples: Input : s = "abcbab", l = 2 Output : 4 All distinct sub-strings of length 2 will be {"ab", "bc", "cb", "ba"} Thus, answer eq
6 min read
Number of distinct permutation a String can have
We are given a string having only lowercase alphabets. The task is to find out total number of distinct permutation can be generated by that string. Examples: Input : aab Output : 3 Different permutations are "aab", "aba" and "baa". Input : ybghjhbuytb Output : 1663200 A simple solution is to find a
6 min read
Count of distinct permutation of a String obtained by swapping only unequal characters
Given a string find the number of unique permutations that can be obtained by swapping two indices such that the elements at these indices are distinct. NOTE: Swapping is always performed in the original string. Examples: Input: str = "sstt"Output: 5Explanation: Swap str[0] with str[2], string obtai
11 min read
Count of Distinct strings possible by inserting K characters in the original string
Given a string S and an integer K, the task is to find the total number of strings that can be formed by inserting exactly K characters at any position of the string S. Since the answer can be large, print it modulo 109+7.Examples: Input: S = "a" K = 1 Output: 51 Explanation: Since any of the 26 cha
12 min read
Count of distinct Strings possible by swapping prefixes of pairs of Strings from the Array
Given an array string[] consisting of N numeric strings of length M, the task is to find the number of distinct strings that can be generated by selecting any two strings, say i and j from the array and swap all possible prefixes between them. Note: Since the answer can be very large, print modulo 1
6 min read
Count of Distinct Substrings occurring consecutively in a given String
Given a string str, the task is to find the number of distinct substrings that are placed consecutively in the given string. Examples: Input: str = "geeksgeeksforgeeks" Output: 2 Explanation: geeksgeeksforgeeks -> {"geeks"} geeksgeeksforgeeks -> {"e"} Only one consecutive occurrence of "e" is
14 min read
Print all distinct circular strings of length M in lexicographical order
Given a string and an integer M, print all distinct circular strings of length M in lexicographical order. Examples: Input: str = "baaaa", M = 3 Output: aaa aab aba baa All possible circular substrings of length 3 are "baa" "aaa" "aaa" "aab" "aba" Out of the 6, 4 are distinct, and the lexicographica
5 min read