# Count of pairs of strings whose concatenation forms a palindromic string

Given an array A[ ] consisting of N strings, the task is to count the number of pairs of possible strings that on merging forms a Palindromic String or can be rearranged to form a Palindromic String

Example :

Input: N = 6, A[ ] = {aab, abcac, dffe, ed, aa, aade}
Output: 6
Explanation:
All possible pairs of strings which generates a palindromic string:
{aab, abcac} = aabccbaa
{aab, aa} = aabaa
{abcac, aa} = aacbcaa
{dffe, ed} = fdeedf
Hence, total possible pairs = 6

Input: N = 3, A[ ] = {aa, bb, cd}
Output: 1
Explanation:
The only possible pair of strings which generates palindromic string:
{aa, bb} = abba
Hence, total possible pairs = 1

Naive Approach:
The simplest approach to solve this problem is to generate all possible pairs from the given array and merge these pairs to generate new strings. For each of those merged strings, generate all possible permutations of the string and for each permutation, check whether it is a palindromic string or not and increment the count accordingly.
Time Complexity: O(N2 * L! * L), where L is the maximum length of a string.
Auxiliary Space: O(M)

Efficient Approach:
A palindromic string can always be formed when at most one character has an odd occurrence and remaining every character has even occurrence. Since rearrangement of the characters in the merged string is allowed, so we only need to count the frequency of characters in the merged string and check if it satisfies to be a palindromic string or not.

Illustration:
1. Every character has even occurrence
Strings “aab” and “abcac” can be merged and rearranged to form a palindromic string “aababcac” with each character having even frequency

2. One character has odd occurrence
Strings “aab” and “aa” can be merged to form a palindromic string “aabaa” with a character(‘b’) having odd frequency and the rest having even frequency.

Hence, it can be observed that two pairs of strings of the following types can be merged to form a palindromic string:

• The frequency of each character in both strings are same.
• At most one character in both the strings has a different frequency.

Follow the steps below to solve the problem:

• Traverse the given array and for every string,  store the frequency of each character.
• Assign parity (0 or 1) to each frequency. Assign 0 for even frequency and 1 for odd frequency.
• Initialize a map to store the frequencies of each frequency array generated.
• Since, rearrangement is allowed, reverse the parity of each character and include the frequency array in map.
• Finally, return the total count of similar frequency arrays, which will give the required count of pairs.

Below is the implementation of the above approach:

## C++

 `// C++ Program to find ``// palindromic string ``#include ``using` `namespace` `std; ` `int` `getCount(``int` `N, vector& s) ``{ ``    ``// Stores frequency array ``    ``// and its count ``    ``map, ``int``> mp; ` `    ``// Total number of pairs ``    ``int` `ans = 0; ` `    ``for` `(``int` `i = 0; i < N; i++) { ` `        ``// Initializing array of size 26 ``        ``// to store count of character ``        ``vector<``int``> a(26, 0); ` `        ``// Counting occurrence of each ``        ``// character of current string ``        ``for` `(``int` `j = 0; j < s[i].size(); j++) { ` `            ``a[s[i][j] - ``'a'``]++; ``        ``} ` `        ``// Convert each count to parity(0 or 1) ``        ``// on the basis of its frequency ``        ``for` `(``int` `j = 0; j < 26; j++) { ` `            ``a[j] = a[j] % 2; ``        ``} ` `        ``// Adding to answer ``        ``ans += mp[a]; ` `        ``// Frequency of single character ``        ``// can be possibly changed, ``        ``// so change its parity ``        ``for` `(``int` `j = 0; j < 26; j++) { ` `            ``vector<``int``> changedCount = a; ` `            ``if` `(a[j] == 0) ``                ``changedCount[j] = 1; ``            ``else``                ``changedCount[j] = 0; ` `            ``ans += mp[changedCount]; ``        ``} ` `        ``mp[a]++; ``    ``} ` `    ``return` `ans; ``} ` `int` `main() ``{ ``    ``int` `N = 6; ``    ``vector A ``        ``= { ``"aab"``, ``"abcac"``, ``"dffe"``, ``            ``"ed"``, ``"aa"``, ``"aade"` `}; ` `    ``cout << getCount(N, A); ` `    ``return` `0; ``}`

## Java

 `// Java program to find ``// palindromic string ``import` `java.util.*;` `class` `GFG{` `static` `int` `getCount(``int` `N, List s) ``{ ``    ` `    ``// Stores frequency array ``    ``// and its count ``    ``Map, Integer> mp = ``new` `HashMap<>(); ``    ` `    ``// Total number of pairs ``    ``int` `ans = ``0``; ``    ` `    ``for``(``int` `i = ``0``; i < N; i++)``    ``{ ``        ` `        ``// Initializing array of size 26 ``        ``// to store count of character ``        ``List a = ``new` `ArrayList<>(``26``);``        ``for``(``int` `k = ``0``; k < ``26``; k++)``            ``a.add(``0``);``        ` `        ``// Counting occurrence of each ``        ``// character of current string ``        ``for``(``int` `j = ``0``; j < s.get(i).length(); j++)``        ``{ ``            ``a.set((s.get(i).charAt(j) - ``'a'``),``             ``a.get(s.get(i).charAt(j) - ``'a'``) + ``1``); ``        ``} ` `        ``// Convert each count to parity(0 or 1) ``        ``// on the basis of its frequency ``        ``for``(``int` `j = ``0``; j < ``26``; j++)``        ``{ ``            ``a.set(j, a.get(j) % ``2``);``        ``} ``        ` `        ``// Adding to answer ``        ``ans += mp.getOrDefault(a, ``0``); ``        ` `        ``// Frequency of single character ``        ``// can be possibly changed, ``        ``// so change its parity ``        ``for``(``int` `j = ``0``; j < ``26``; j++) ``        ``{ ``            ``List changedCount = ``new` `ArrayList<>();``            ``changedCount.addAll(a);``            ` `            ``if` `(a.get(j) == ``0``) ``                ``changedCount.set(j, ``1``); ``            ``else``                ``changedCount.set(j, ``0``); ``            ` `            ``ans += mp.getOrDefault(changedCount, ``0``); ``        ``} ``        ``mp.put(a, mp.getOrDefault(a, ``0``) + ``1``);``    ``} ``    ``return` `ans; ``}` `// Driver code``public` `static` `void` `main (String[] args)``{``    ``int` `N = ``6``; ``    ``List A = Arrays.asList(``"aab"``, ``"abcac"``,``                                   ``"dffe"``, ``"ed"``, ``                                   ``"aa"``, ``"aade"``); ``    ` `    ``System.out.print(getCount(N, A)); ``}``}` `// This code is contributed by offbeat`

## Python3

 `# Python3 program to find ``# palindromic string ``from` `collections ``import` `defaultdict ` `def` `getCount(N, s): ` `    ``# Stores frequency array ``    ``# and its count ``    ``mp ``=` `defaultdict(``lambda``: ``0``) ` `    ``# Total number of pairs ``    ``ans ``=` `0` `    ``for` `i ``in` `range``(N): ` `        ``# Initializing array of size 26 ``        ``# to store count of character ``        ``a ``=` `[``0``] ``*` `26` `        ``# Counting occurrence of each ``        ``# character of current string ``        ``for` `j ``in` `range``(``len``(s[i])): ``            ``a[``ord``(s[i][j]) ``-` `ord``(``'a'``)] ``+``=` `1` `        ``# Convert each count to parity(0 or 1) ``        ``# on the basis of its frequency ``        ``for` `j ``in` `range``(``26``): ``            ``a[j] ``=` `a[j] ``%` `2` `        ``# Adding to answer ``        ``ans ``+``=` `mp[``tuple``(a)] ` `        ``# Frequency of single character ``        ``# can be possibly changed, ``        ``# so change its parity ``        ``for` `j ``in` `range``(``26``): ``            ``changedCount ``=` `a[:] ``            ``if` `(a[j] ``=``=` `0``): ``                ``changedCount[j] ``=` `1``            ``else``: ``                ``changedCount[j] ``=` `0``            ``ans ``+``=` `mp[``tuple``(changedCount)] ` `        ``mp[``tuple``(a)] ``+``=` `1` `    ``return` `ans ` `# Driver code ``if` `__name__ ``=``=` `'__main__'``: ``    ` `    ``N ``=` `6``    ``A ``=` `[ ``"aab"``, ``"abcac"``, ``"dffe"``, ``        ``"ed"``, ``"aa"``, ``"aade"` `] ` `    ``print``(getCount(N, A)) ` `# This code is contributed by Shivam Singh `

## C#

 `// C# program to find``// palindromic string``using` `System;``using` `System.Collections.Generic;` `class` `GFG {` `  ``static` `int` `CompareLists(List<``int``> a, List<``int``> b)``  ``{``    ` `    ``// Check the length of both lists first``    ``if` `(a.Count != b.Count) {``      ``return` `a.Count - b.Count;``    ``}` `    ``// Compare each element of the lists``    ``for` `(``int` `i = 0; i < a.Count; i++) {``      ``if` `(a[i] != b[i]) {``        ``return` `a[i] - b[i];``      ``}``    ``}` `    ``return` `0;``  ``}` `  ``static` `int` `getCount(``int` `N, List<``string``> s)``  ``{` `    ``// Stores frequency array``    ``// and its count``    ``Dictionary, ``int``> mp``      ``= ``new` `Dictionary, ``int``>(``      ``new` `ListComparer());` `    ``// Total number of pairs``    ``int` `ans = 0;` `    ``for` `(``int` `i = 0; i < N; i++) {` `      ``// Initializing array of size 26``      ``// to store count of character``      ``List<``int``> a = ``new` `List<``int``>(``new` `int``[26]);` `      ``// Counting occurrence of each``      ``// character of current string``      ``for` `(``int` `j = 0; j < s[i].Length; j++) {``        ``a[s[i][j] - ``'a'``]++;``      ``}` `      ``// Convert each count to parity(0 or 1)``      ``// on the basis of its frequency``      ``for` `(``int` `j = 0; j < 26; j++) {``        ``a[j] %= 2;``      ``}` `      ``// Adding to answer``      ``ans += mp.GetValueOrDefault(a, 0);` `      ``// Frequency of single character``      ``// can be possibly changed,``      ``// so change its parity``      ``for` `(``int` `j = 0; j < 26; j++) {``        ``List<``int``> changedCount = ``new` `List<``int``>(a);` `        ``if` `(a[j] == 0)``          ``changedCount[j] = 1;``        ``else``          ``changedCount[j] = 0;` `        ``ans += mp.GetValueOrDefault(changedCount,``                                    ``0);``      ``}``      ``mp[a] = mp.GetValueOrDefault(a, 0) + 1;``    ``}``    ``return` `ans;``  ``}` `  ``// Driver code``  ``static` `void` `Main(``string``[] args)``  ``{``    ``int` `N = 6;``    ``List<``string``> A``      ``= ``new` `List<``string``>{ ``"aab"``, ``"abcac"``, ``"dffe"``,``                         ``"ed"``,  ``"aa"``,    ``"aade"` `};` `    ``Console.Write(getCount(N, A));``  ``}``}` `class` `ListComparer : IEqualityComparer > {``  ``public` `bool` `Equals(List<``int``> a, List<``int``> b)``  ``{``    ` `    ``// Compare the elements of both lists``    ``if` `(a.Count != b.Count) {``      ``return` `false``;``    ``}` `    ``for` `(``int` `i = 0; i < a.Count; i++) {``      ``if` `(a[i] != b[i]) {``        ``return` `false``;``      ``}``    ``}` `    ``return` `true``;``  ``}` `  ``public` `int` `GetHashCode(List<``int``> list)``  ``{``    ` `    ``// Generate a hash code based on the elements of the``    ``// list``    ``int` `hash = 17;` `    ``foreach``(``int` `element ``in` `list)``    ``{``      ``hash = hash * 31 + element;``    ``}``    ``return` `hash;``  ``}``}` `// This code is contributed by phasing17`

## Javascript

 `// JS Program to find ``// palindromic string ` `function` `getCount(N, s) {``  ``// Stores frequency array ``  ``// and its count ``  ``let mp = ``new` `Map();` `  ``// Total number of pairs ``  ``let ans = 0;` `  ``for` `(let i = 0; i < N; i++) {` `    ``// Initializing array of size 26 ``    ``// to store count of character ``    ``let a = [];``    ``for` `(let i = 0; i < 26; i++) {``      ``a.push(0);``    ``}` `    ``// Counting occurrence of each ``    ``// character of current string ``    ``for` `(let j = 0; j < s[i].length; j++) {``      ``// console.log("p : ",);` `      ``a[s[i][j].charCodeAt(0) - ``'a'``.charCodeAt(0)]++;``    ``}` `    ``// Convert each count to parity(0 or 1) ``    ``// on the basis of its frequency ``    ``for` `(let j = 0; j < 26; j++) {` `      ``a[j] = a[j] % 2;``    ``}` `    ``// Adding to answer ``    ``let str = ``""``;``    ``for` `(let m = 0; m < a.length; m++) {``      ``str += a[m];``    ``}``    ``if` `(!mp.has(str)) {``      ``mp.set(str, 0);``      ``ans += mp.get(str);``    ``}``    ``else``      ``ans += mp.get(str);`  `    ``// Frequency of single character ``    ``// can be possibly changed, ``    ``// so change its parity ``    ``for` `(let j = 0; j < 2; j++) {` `      ``let changedCount = a;` `      ``if` `(a[j] == 0)``        ``changedCount[j] = 1;``      ``else``        ``changedCount[j] = 0;` `      ``let str2 = ``""``;``      ``for` `(let p = 0; p < changedCount.length; p++) {``        ``str2 += changedCount[p];``      ``}``      ``if` `(!mp.has(str2)) {``        ``mp.set(str2, 0);``        ``ans += mp.get(str2);``      ``}``      ``else``        ``ans += mp.get(str2);``    ``}``    ``mp.set(str, mp.get(str)+1.5);``  ``}` `  ``return` `ans;``}`  `let N = 6;``let A = [``"aab"``, ``"abcac"``, ``"dffe"``, ``"ed"``, ``"aa"``, ``"aade"``];` `console.log(getCount(N, A));` `// This code is contributed by ksam24000.`

Output:
`6`

Time Complexity: O(N*(L+log(N))), where L is the maximum length of a string
Auxiliary Space: O(N)

Previous
Next