Given an array of lower case strings, the task is to find the number of strings that are distinct. Two strings are distinct if, on applying the following operations on one string, the second string cannot be formed.
- A character on the odd index can be swapped with another character on the odd index only.
- A character on even index can be swapped with another character on even index only.
Examples:
Input : arr[] = {"abcd", "cbad", "bacd"}
Output : 2
The 2nd string can be converted to the 1st by swapping
the first and third characters. So there are 2 distinct
strings as the third string cannot be converted to the
first.
Input : arr[] = {"abc", "cba"}
Output : 1
A simple solution is to run two loops. The outer loop picks a string and the inner loop checks if there is a previously string which can be converted to a current string by doing allowed transformations. This solution requires O(n2m) time where n is the number of strings and m is the maximum number of characters in any string.
An efficient solution generates an encoded string for every input string. The encoded has counts of even and odd positioned characters separated by a separator. Two strings are considered same if their encoded strings are the same, then else not. Once we have a way to encode strings, the problem is reduced to counting distinct encoded strings. This is a typical problem of hashing. We create a hash set and, one by one, store encodings of strings. If an encoding already exists, we ignore the string. Otherwise, we store encoding in hash and increment count of distinct strings.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int MAX_CHAR = 26;
string encodeString( char str[], int m) {
int hashEven[MAX_CHAR];
int hashOdd[MAX_CHAR];
memset (hashEven,0, sizeof (hashEven));
memset (hashOdd,0, sizeof (hashOdd));
for ( int i = 0; i < m; i++) {
char c = str[i];
if ((i & 1) != 0)
hashOdd[c- 'a' ]++;
else
hashEven[c- 'a' ]++;
}
string encoding = "" ;
for ( int i = 0; i < MAX_CHAR; i++) {
encoding += (hashEven[i]);
encoding += ( '-' );
encoding += (hashOdd[i]);
encoding += ( '-' );
}
return encoding;
}
int countDistinct(string input[], int n) {
int countDist = 0;
set<string> s;
for ( int i = 0; i < n; i++) {
char char_array[input[i].length()];
strcpy (char_array, input[i].c_str());
if (s.find(encodeString(char_array, input[i].length())) == s.end()) {
s.insert(encodeString(char_array,input[i].length()));
countDist++;
}
}
return countDist;
}
int main() {
string input[] = { "abcd" , "acbd" , "adcb" , "cdba" ,
"bcda" , "badc" };
int n = sizeof (input)/ sizeof (input[0]);
cout << countDistinct(input, n) << "\n" ;
}
|
Java
import java.util.HashSet;
import java.util.Set;
class GFG {
static int MAX_CHAR = 26 ;
static String encodeString( char [] str) {
int hashEven[] = new int [MAX_CHAR];
int hashOdd[] = new int [MAX_CHAR];
for ( int i = 0 ; i < str.length; i++) {
char c = str[i];
if ((i & 1 ) != 0 )
hashOdd[c- 'a' ]++;
else
hashEven[c- 'a' ]++;
}
String encoding = "" ;
for ( int i = 0 ; i < MAX_CHAR; i++) {
encoding += (hashEven[i]);
encoding += ( '-' );
encoding += (hashOdd[i]);
encoding += ( '-' );
}
return encoding;
}
static int countDistinct(String input[], int n) {
int countDist = 0 ;
Set<String> s = new HashSet<>();
for ( int i = 0 ; i < n; i++) {
if (!s.contains(encodeString(input[i].toCharArray()))) {
s.add(encodeString(input[i].toCharArray()));
countDist++;
}
}
return countDist;
}
public static void main(String[] args) {
String input[] = { "abcd" , "acbd" , "adcb" , "cdba" ,
"bcda" , "badc" };
int n = input.length;
System.out.println(countDistinct(input, n));
}
}
|
Python3
MAX_CHAR = 26
def encodeString(string):
hashEven = [ 0 ] * MAX_CHAR
hashOdd = [ 0 ] * MAX_CHAR
for i in range ( len (string)):
c = string[i]
if i & 1 :
hashOdd[ ord (c) - ord ( 'a' )] + = 1
else :
hashEven[ ord (c) - ord ( 'a' )] + = 1
encoding = ""
for i in range (MAX_CHAR):
encoding + = str (hashEven[i])
encoding + = str ( '-' )
encoding + = str (hashOdd[i])
encoding + = str ( '-' )
return encoding
def countDistinct( input , n):
countDist = 0
s = set ()
for i in range (n):
if encodeString( input [i]) not in s:
s.add(encodeString( input [i]))
countDist + = 1
return countDist
if __name__ = = "__main__" :
input = [ "abcd" , "acbd" , "adcb" ,
"cdba" , "bcda" , "badc" ]
n = len ( input )
print (countDistinct( input , n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX_CHAR = 26;
static String encodeString( char [] str)
{
int []hashEven = new int [MAX_CHAR];
int []hashOdd = new int [MAX_CHAR];
for ( int i = 0; i < str.Length; i++)
{
char m = str[i];
if ((i & 1) != 0)
hashOdd[m - 'a' ]++;
else
hashEven[m - 'a' ]++;
}
String encoding = "" ;
for ( int i = 0; i < MAX_CHAR; i++)
{
encoding += (hashEven[i]);
encoding += ( '-' );
encoding += (hashOdd[i]);
encoding += ( '-' );
}
return encoding;
}
static int countDistinct(String []input, int n)
{
int countDist = 0;
HashSet<String> s = new HashSet<String>();
for ( int i = 0; i < n; i++)
{
if (!s.Contains(encodeString(input[i].ToCharArray())))
{
s.Add(encodeString(input[i].ToCharArray()));
countDist++;
}
}
return countDist;
}
public static void Main(String[] args)
{
String []input = { "abcd" , "acbd" , "adcb" ,
"cdba" , "bcda" , "badc" };
int n = input.Length;
Console.WriteLine(countDistinct(input, n));
}
}
|
Javascript
<script>
let MAX_CHAR = 26;
function encodeString(str) {
let hashEven = Array(MAX_CHAR).fill(0);
let hashOdd = Array(MAX_CHAR).fill(0);
for (let i = 0; i < str.length; i++) {
let c = str[i];
if ((i & 1) != 0)
hashOdd[c.charCodeAt() - 'a' .charCodeAt()]++;
else
hashEven[c.charCodeAt() - 'a' .charCodeAt()]++;
}
let encoding = "" ;
for (let i = 0; i < MAX_CHAR; i++) {
encoding += (hashEven[i]);
encoding += ( '-' );
encoding += (hashOdd[i]);
encoding += ( '-' );
}
return encoding;
}
function countDistinct(input, n) {
let countDist = 0;
let s = new Set();
for (let i = 0; i < n; i++) {
if (!s.has(encodeString(input[i].split( '' )))) {
s.add(encodeString(input[i].split( '' )));
countDist++;
}
}
return countDist;
}
let input = [ "abcd" , "acbd" , "adcb" , "cdba" ,
"bcda" , "badc" ];
let n = input.length;
document.write(countDistinct(input, n));
</script>
|
Time complexity : O(n)
Auxiliary Space : O(1)
This article is contributed by harshitsharma6091. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.