Related Articles

# Distinct strings with odd and even changes allowed

• Difficulty Level : Medium
• Last Updated : 28 Jun, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

```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 distinct 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.

## C++

 `#include``using` `namespace` `std;` `int` `MAX_CHAR = 26;` `    ``string encodeString(``char` `str[], ``int` `m) {``        ``// hashEven stores the count of even indexed character``        ``// for each string hashOdd stores the count of odd``        ``// indexed characters for each string``        ``int` `hashEven[MAX_CHAR];``        ``int` `hashOdd[MAX_CHAR];` `        ``// creating hash for each string``        ``for` `(``int` `i = 0; i < m; i++) {``            ``char` `c = str[i];``            ``if` `((i & 1) != 0) ``// If index of current character is odd``                ``hashOdd[c-``'a'``]++;``            ``else``                ``hashEven[c-``'a'``]++;` `        ``}`  `        ``// For every character from 'a' to 'z', we store its``        ``// count at even position followed by a separator,``        ``// followed by count at odd position.``        ``string encoding = ``""``;``        ``for` `(``int` `i = 0; i < MAX_CHAR; i++) {``            ``encoding += (hashEven[i]);``            ``encoding += (``'-'``);``            ``encoding += (hashOdd[i]);``            ``encoding += (``'-'``);``        ``}``        ``return` `encoding;``    ``}` `    ``// This function basically uses a hashing based set to``// store strings which are distinct according to according``// to criteria given in question.``    ``int` `countDistinct(string input[], ``int` `n) {``        ``int` `countDist = 0; ``// Initialize result` `        ``// Create an empty set and store all distinct``        ``// strings in it.``        ``set s;``        ``for` `(``int` `i = 0; i < n; i++) {``            ``// If this encoding appears first time, increment``            ``// count of distinct encodings.``              ``char` `char_array[input[i].length()+1];``              ``strcpy``(char_array, input[i].c_str());``            ``if` `(s.find(encodeString(char_array, input[i].length()+1)) == s.end()) {``                ``s.insert(encodeString(char_array,input[i].length()+1));``                ``countDist++;``            ``}``        ``}` `        ``return` `countDist;``    ``}` `// Driver code``    ``int` `main() {``        ``string input[] = {``"abcd"``, ``"acbd"``, ``"adcb"``, ``"cdba"``,``                ``"bcda"``, ``"badc"``};``        ``int` `n = ``sizeof``(input)/``sizeof``(input);` `        ``cout << countDistinct(input, n) << ``"\n"``;``    ``}` `// This code is contributed by NishaBharti.`

## Java

 `// Java program to count distinct strings with``// even odd swapping allowed.``import` `java.util.HashSet;``import` `java.util.Set;``class` `GFG {``static` `int` `MAX_CHAR = ``26``;` `    ``static` `String encodeString(``char``[] str) {``        ``// hashEven stores the count of even indexed character``        ``// for each string hashOdd stores the count of odd``        ``// indexed characters for each string``        ``int` `hashEven[] = ``new` `int``[MAX_CHAR];``        ``int` `hashOdd[] = ``new` `int``[MAX_CHAR];` `        ``// creating hash for each string``        ``for` `(``int` `i = ``0``; i < str.length; i++) {``            ``char` `c = str[i];``            ``if` `((i & ``1``) != ``0``) ``// If index of current character is odd``                ``hashOdd[c-``'a'``]++;``            ``else``                ``hashEven[c-``'a'``]++;` `        ``}`  `        ``// For every character from 'a' to 'z', we store its``        ``// count at even position followed by a separator,``        ``// followed by count at odd position.``        ``String encoding = ``""``;``        ``for` `(``int` `i = ``0``; i < MAX_CHAR; i++) {``            ``encoding += (hashEven[i]);``            ``encoding += (``'-'``);``            ``encoding += (hashOdd[i]);``            ``encoding += (``'-'``);``        ``}``        ``return` `encoding;``    ``}` `    ``// This function basically uses a hashing based set to``// store strings which are distinct according to according``// to criteria given in question.``    ``static` `int` `countDistinct(String input[], ``int` `n) {``        ``int` `countDist = ``0``; ``// Initialize result` `        ``// Create an empty set and store all distinct``        ``// strings in it.``        ``Set s = ``new` `HashSet<>();``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``// If this encoding appears first time, increment``            ``// count of distinct encodings.``            ``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

 `# Python3 program to count distinct strings with``# even odd swapping allowed.``MAX_CHAR ``=` `26` `# Returns encoding of string that can be used``# for hashing. The idea is to return same encoding``# for strings which can become same after swapping``# a even positioned character with other even characters``# OR swapping an odd character with other odd characters.``def` `encodeString(string):` `    ``# hashEven stores the count of even indexed character``    ``# for each string hashOdd stores the count of odd``    ``# indexed characters for each string``    ``hashEven ``=` `[``0``] ``*` `MAX_CHAR``    ``hashOdd ``=` `[``0``] ``*` `MAX_CHAR` `    ``# creating hash for each string``    ``for` `i ``in` `range``(``len``(string)):``        ``c ``=` `string[i]``        ``if` `i & ``1``: ``# If index of current character is odd``            ``hashOdd[``ord``(c) ``-` `ord``(``'a'``)] ``+``=` `1``        ``else``:``            ``hashEven[``ord``(c) ``-` `ord``(``'a'``)] ``+``=` `1` `    ``# For every character from 'a' to 'z', we store its``    ``# count at even position followed by a separator,``    ``# followed by count at odd position.``    ``encoding ``=` `""``    ``for` `i ``in` `range``(MAX_CHAR):``        ``encoding ``+``=` `str``(hashEven[i])``        ``encoding ``+``=` `str``(``'-'``)``        ``encoding ``+``=` `str``(hashOdd[i])``        ``encoding ``+``=` `str``(``'-'``)` `    ``return` `encoding` `# This function basically uses a hashing based set to``# store strings which are distinct according to according``# to criteria given in question.``def` `countDistinct(``input``, n):``    ``countDist ``=` `0` `# Initialize result` `    ``# Create an empty set and store all distinct``    ``# strings in it.``    ``s ``=` `set``()``    ``for` `i ``in` `range``(n):` `        ``# If this encoding appears first time, increment``        ``# count of distinct encodings.``        ``if` `encodeString(``input``[i]) ``not` `in` `s:``            ``s.add(encodeString(``input``[i]))``            ``countDist ``+``=` `1` `    ``return` `countDist` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``input` `=` `[``"abcd"``, ``"acbd"``, ``"adcb"``,``             ``"cdba"``, ``"bcda"``, ``"badc"``]``    ``n ``=` `len``(``input``)``    ``print``(countDistinct(``input``, n))` `# This code is contributed by``# sanjeev2552`

## C#

 `// C# program to count distinct strings with``// even odd swapping allowed.``using` `System;``using` `System.Collections.Generic;``    ` `class` `GFG``{``    ``static` `int` `MAX_CHAR = 26;` `    ``static` `String encodeString(``char``[] str)``    ``{``        ``// hashEven stores the count of even``        ``// indexed character for each string``        ``// hashOdd stores the count of odd``        ``// indexed characters for each string``        ``int` `[]hashEven = ``new` `int``[MAX_CHAR];``        ``int` `[]hashOdd = ``new` `int``[MAX_CHAR];` `        ``// creating hash for each string``        ``for` `(``int` `i = 0; i < str.Length; i++)``        ``{``            ``char` `m = str[i];``            ` `            ``// If index of current character is odd``            ``if` `((i & 1) != 0)``                ``hashOdd[m - ``'a'``]++;``            ``else``                ``hashEven[m - ``'a'``]++;``        ``}` `        ``// For every character from 'a' to 'z',``        ``// we store its count at even position``        ``// followed by a separator,``        ``// followed by count at odd position.``        ``String encoding = ``""``;``        ``for` `(``int` `i = 0; i < MAX_CHAR; i++)``        ``{``            ``encoding += (hashEven[i]);``            ``encoding += (``'-'``);``            ``encoding += (hashOdd[i]);``            ``encoding += (``'-'``);``        ``}``        ``return` `encoding;``    ``}` `    ``// This function basically uses a hashing based set``    ``// to store strings which are distinct according``    ``// to criteria given in question.``    ``static` `int` `countDistinct(String []input, ``int` `n)``    ``{``        ``int` `countDist = 0; ``// Initialize result` `        ``// Create an empty set and store all distinct``        ``// strings in it.``        ``HashSet s = ``new` `HashSet();``        ``for` `(``int` `i = 0; i < n; i++)``        ``{``            ``// If this encoding appears first time,``            ``// increment count of distinct encodings.``            ``if` `(!s.Contains(encodeString(input[i].ToCharArray())))``            ``{``                ``s.Add(encodeString(input[i].ToCharArray()));``                ``countDist++;``            ``}``        ``}` `        ``return` `countDist;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``String []input = {``"abcd"``, ``"acbd"``, ``"adcb"``,``                          ``"cdba"``, ``"bcda"``, ``"badc"``};``        ``int` `n = input.Length;` `        ``Console.WriteLine(countDistinct(input, n));``    ``}``}` `// This code is contributed by 29AjayKumar`

## Javascript

 ``
Output
`4`

This article is contributed by kp93. 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.