Count of pairs of strings whose concatenation forms a palindromic string
Last Updated :
11 Mar, 2023
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
{dffe, aade} = edfaafde
{ed, aade} = edaade or aeddea
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 <bits/stdc++.h>
using namespace std;
int getCount(int N, vector<string>& s)
{
// Stores frequency array
// and its count
map<vector<int>, 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<string> 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<String> s)
{
// Stores frequency array
// and its count
Map<List<Integer>, 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<Integer> 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<Integer> 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<String> 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<List<int>, int> mp
= new Dictionary<List<int>, 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<List<int> > {
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.
Time Complexity: O(N*(L+log(N))), where L is the maximum length of a string
Auxiliary Space: O(N)
Similar Reads
Count pair of strings whose concatenation of substrings form a palindrome
Given an array of strings arr[], the task is to count the pair of strings whose concatenation of substrings form a palindrome.Examples: Input: arr[] = {"gfg", "gfg"} Output: 1 Explanation: One possible way of choosing s1 and s2 is s1 = "gf", s2 = "g" such that s1 + s2 i.e "gfg" is a palindrome.Input
5 min read
Count of three non-overlapping sub-strings which on concatenation forms a palindrome
Given a string str, the task is to count the number of ways a palindromic substring could be formed by the concatenation of three sub-strings x, y and z of the string str such that all of them are non-overlapping i.e. sub-string y occurs after substring x and sub-string z occurs after sub-string y.E
7 min read
Number of pairs of String whose concatenation leads to a Sorted string
Given an array of strings S with the size of N where each string contains at least two distinct characters. The task is to find the number of pairs of strings ( s[i], s[j] ) whose concatenation forms a string that is alphabetically sorted. Here concatenation is simply the process of appending one st
9 min read
Count pairs of non-overlapping palindromic sub-strings of the given string
Given a string S. The task is to count the non-overlapping pairs of palindromic sub-strings S1 and S2 such that the strings should be S1[L1...R1] and S2[L2...R2] where 0 ? L1 ? R1 < L2 ? R2 < N. The task is to count the number of pairs of the non-overlapping palindromic sub-strings. Examples:
13 min read
Check if concatenation of splitted substrings of two given strings forms a palindrome or not
Given two strings a and b of the same length, the task is to check if splitting both the strings and concatenating their opposite substrings, i.e. concatenating the left substring of a with right substring of b or concatenating the left substring of b with right substring of a, forms a palindrome or
8 min read
Longest palindromic string formed by concatenation of prefix and suffix of a string
Given string str, the task is to find the longest palindromic substring formed by the concatenation of the prefix and suffix of the given string str. Examples: Input: str = "rombobinnimor" Output: rominnimor Explanation: The concatenation of string "rombob"(prefix) and "mor"(suffix) is "rombobmor" w
10 min read
Count pairs of non overlapping Substrings of size K which form a palindromic String
Given a string S of length l, the task is to count the number of pairs of two non-overlapping substrings of length K of the string S, such that on joining the two non-overlapping substrings the resultant string is a palindrome. Examples: Input: S = "abcdbadc", K = 2Output: 2 Explanation: Possible su
15 min read
Find the count of palindromic sub-string of a string in its sorted form
Given string str consisting of lowercase English alphabets, the task is to find the total number of palindromic sub-strings present in the sorted form of str. Examples: Input: str = "acbbd" Output: 6 All palindromic sub-string in it's sorted form ("abbcd") are "a", "b", "b", "bb", "c" and "d". Input
5 min read
Count substrings of a given string whose anagram is a palindrome
Given a string S of length N containing only lowercase alphabets, the task is to print the count of substrings of the given string whose anagram is palindromic. Examples: Input: S = "aaaa"Output: 10Explanation:Possible substrings are {"a", "a", "a", "a", "aa", "aa", "aa", "aaa", "aaa", "aaaa"}. Sinc
10 min read
Count of Palindromic Strings possible by swapping of a pair of Characters
Given a palindromic string S, the task is to find the count of palindromic strings possible by swapping a pair of character at a time.Examples: Input: s = "abba" Output: 2 Explanation: 1st Swap: abba -> abba 2nd Swap: abba -> abba All other swaps will lead to a non-palindromic string. Therefor
4 min read