Making a Palindrome pair in an array of words (or strings) in C++

C++Server Side ProgrammingProgramming

"Madam" or "racecar" are two words that read the same backward as forwards, called palindromes.

If we are given a collection or list of strings, we have to write a C++ code to find out if that can join any two strings in the list together to form a palindrome or not. If any such pair of strings exist in the given list, we have to print "Yes," else we have to print "No."

In this tutorial, input will be an array of strings, and output will be a string value accordingly, for example

Input

list[] = {"flat", "tea", "chair", "ptalf", "tea"}

Output

Yes

There is a pair "flat" and "ptalf" which forms a palindrome string "flatptalf".

Input

list[] = {"raman", "ram", "na", "ar", "man"}

Output

Yes

There is a pair "na" and "man" which forms a palindrome string "naman".

Approach to Find the Solution

Brute Force Approach

For each string in the array, check all other strings if it forms a palindrome with any other string or not. If such a pair is found, return true. If all the array elements are traversed for searching such a pair, and no suitable pair is found, return false.

Time Complexity : O(N^2)

Space Complexity : O(1)

Example

#include<bits/stdc++.h>
using namespace std;
bool isPalindrome (string str) {
   int len = str.length ();
   for (int i = 0; i < len / 2; i++)
   if (str[i] != str[len - i - 1])
      return false;
   return true;
}
bool checkPalindromePair (vector < string > vect) {
   for (int i = 0; i < vect.size () - 1; i++) {
      for (int j = i + 1; j < vect.size (); j++) {
         string check_str = "";
         check_str = check_str + vect[i] + vect[j];
         if (isPalindrome (check_str))
            return true;
      }
   }
   return false;
}
int main () {
   vector < string > vect = { "flat", "tea", "chair", "ptalf", "tea"};
   checkPalindromePair (vect) ? cout << "Yes" : cout << "No";
   return 0;
}

Output

Yes

Efficient or Optimized Approach

We could use a trie data structure to solve this problem.

First, we have to create an empty trie, and for each string in the array, we have to insert the reverse of the current word & also store up to which index it is a palindrome. Then we have to traverse the array again, and for each string, we have to do the following-

  • If it is available in True, then return true

  • If it is partially available --Check the remaining word is palindrome or not If yes, then return true that means a pair forms a palindrome.

Time Complexity: O(Nk^2)

Space Complexity: O(N)

Where N is the number of words in the list and k is the maximum length checked for palindrome.

Example 2

#include<bits/stdc++.h>
using namespace std;
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
#define ALPHABET_SIZE (26)
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
struct TrieNode {
   struct TrieNode *children[ALPHABET_SIZE];
   vector < int >pos;
   int id;
   bool isLeaf;
};
struct TrieNode *
getNode (void) {
   struct TrieNode *pNode = new TrieNode;
   pNode->isLeaf = false;
   for (int i = 0; i < ALPHABET_SIZE; i++)
      pNode->children[i] = NULL;
   return pNode;
}
bool isPalindrome (string str, int i, int len) {
   while (i < len) {
      if (str[i] != str[len])
         return false;
      i++, len--;
   }
   return true;
}
void insert (struct TrieNode *root, string key, int id) {
   struct TrieNode *pCrawl = root;
   for (int level = key.length () - 1; level >= 0; level--) {
      int index = CHAR_TO_INDEX (key[level]);
      if (!pCrawl->children[index])
         pCrawl->children[index] = getNode ();
      if (isPalindrome (key, 0, level))
         (pCrawl->pos).push_back (id);
      pCrawl = pCrawl->children[index];
   }
   pCrawl->id = id; pCrawl->pos.push_back (id);
   pCrawl->isLeaf = true;
}
void
search (struct TrieNode *root, string key, int id,
vector < vector < int > >&result) {
   struct TrieNode *pCrawl = root;
   for (int level = 0; level < key.length (); level++) {
      int index = CHAR_TO_INDEX (key[level]);
      if (pCrawl->id >= 0 && pCrawl->id != id && isPalindrome (key, level, key.size () - 1))             result.push_back ( { id, pCrawl->id} );
      if (!pCrawl->children[index]) return; pCrawl = pCrawl->children[index];
   }
   for (int i:pCrawl->pos) {
      if (i == id) continue;
         result.push_back ( { id, i} );
   }
}
bool checkPalindromePair (vector < string > vect) {
   struct TrieNode *root = getNode ();
   for (int i = 0; i < vect.size (); i++)
   insert (root, vect[i], i);
   vector < vector < int >>result;
   for (int i = 0; i < vect.size (); i++) {
      search (root, vect[i], i, result);
      if (result.size () > 0) return true;
   }
   return false;
}
// Driver code int main () {
   vector < string > vect = { "flat", "tea", "chair", "ptalf", "tea"};
   checkPalindromePair (vect) ? cout << "Yes" : cout << "No";
   return 0;
}

Output

Yes

Conclusion

In this tutorial, we learned how to find a palindrome pair in an array with two approaches (Bruteforce and Optimized). We can also write this code in java, python, and other languages. The first approach is a basic way to find any solution by traversing all the given elements. In contrast, the second approach uses a trie data structure so that it gives out the answer is almost linear time complexity. We hope you find this tutorial helpful.

raja
Updated on 07-Mar-2022 07:45:56

Advertisements