Palindrome Pairs (original) (raw)

Given an array **arr[] consisting ofnstrings. The task is to find if there exists a pair of indices ****(i, j)** such that **i ≠ j and the concatenation **arr[i] + arr[j] forms a palindrome.
Return **true if such a pair exists; otherwise, return **false.

**Note: A string is considered a palindrome if it reads the same forward and backward.

**Examples:

**Input: arr[] = ["geekf", "geeks", "or", "keeg", "abc", "bc"]
**Output: true
**Explanation: Strings "geekf" and "keeg" can be concatenated to form a palindromic string "geekfkeeg" .

**Input: arr[] = ["abc", "xyxcba", "geekst", "or", "keeg", "bc"]
**Output: true
**Explanation: Strings "abc" and "xyxcba" can be concatenated to form a palindromic string "abcxyxcba" .

**Input: arr[] = ["abc", "ab", "xyz"]
**Output: false
**Explanation: No palindromic string can be formed by concatenating any two of the given strings.

Table of Content

[Naive Approach] Using Nested Loop - O(n^2 * k) Time and O(1) Space

The idea is to iteratively generate all possible pairs of strings using the nested loops and check if any of them is a palindrome.

Dry run for arr = ["geekf", "geeks", "or", "keeg", "abc", "bc"]:

Final answer : True

C++ `

#include<bits/stdc++.h> using namespace std;

// Function to check if a string is palindrome bool isPalindrome(string &s) { int n = s.length();

// compare each character from starting
// with its corresponding character from last
for (int i = 0; i < n/2; i++ )
    if (s[i] != s[n-i-1])
        return false;

return true;

}

// Function to check if a palindrome pair exists bool palindromePair(vector &arr) {

// Consider each pair one by one
for (int i = 0; i < arr.size(); i++) {
    for (int j = i + 1; j< arr.size(); j++) {

        // concatenate both strings
        string str = arr[i] + arr[j];

        // check if str is palindrome
        if (isPalindrome(str))
            return true;

        // check for other combination
        str = arr[j] + arr[i];
        if (isPalindrome(str))
            return true;
    }
}
return false;

}

int main() { vector arr = {"geekf", "geeks", "or", "keeg", "abc", "bc"}; if(palindromePair(arr)) cout << "True"; else cout << "False"; return 0; }

Java

import java.util.*;

class GfG {

// Function to check if a string is palindrome
static boolean isPalindrome(String s) {
    int n = s.length();

    // compare each character from starting
    // with its corresponding character from last
    for (int i = 0; i < n / 2; i++)
        if (s.charAt(i) != s.charAt(n - i - 1))
            return false;

    return true;
}

// Function to check if a palindrome pair exists
static boolean palindromePair(String[] arr) {

    // Consider each pair one by one
    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < arr.length; j++) {

            // concatenate both strings
            String str = arr[i] + arr[j];

            // check if str is palindrome
            if (isPalindrome(str))
                return true;

            // check for other combination
            str = arr[j] + arr[i];
            if (isPalindrome(str))
                return true;
        }
    }
    return false;
}

public static void main(String[] args) {
    String[] arr = {"geekf", "geeks", "or", "keeg", "abc", "bc"};
    if (palindromePair(arr))
        System.out.println("True");
    else
        System.out.println("False");
}

}

Python

Function to check if a string is palindrome

def isPalindrome(s): n = len(s)

# compare each character from starting
# with its corresponding character from last
for i in range(n // 2):
    if s[i] != s[n - i - 1]:
        return False

return True

Function to check if a palindrome pair exists

def palindromePair(arr):

# Consider each pair one by one
for i in range(len(arr)):
    for j in range(i + 1, len(arr)):

        # concatenate both strings
        strVal = arr[i] + arr[j]

        # check if str_val is palindrome
        if isPalindrome(strVal):
            return True

        # check for other combination
        strVal = arr[j] + arr[i]
        if isPalindrome(strVal):
            return True

return False

Driver code

if name == "main": arr = ["geekf", "geeks", "or", "keeg", "abc", "bc"] if palindromePair(arr): print("True") else: print("False")

C#

using System;

class GfG {

// Function to check if a string is palindrome
static bool isPalindrome(string s) {
    int n = s.Length;

    // compare each character from starting
    // with its corresponding character from last
    for (int i = 0; i < n / 2; i++)
        if (s[i] != s[n - i - 1])
            return false;

    return true;
}

// Function to check if a palindrome pair exists
static bool palindromePair(string[] arr) {

    // Consider each pair one by one
    for (int i = 0; i < arr.Length; i++) {
        for (int j = i + 1; j < arr.Length; j++) {

            // concatenate both strings
            string str = arr[i] + arr[j];

            // check if str is palindrome
            if (isPalindrome(str))
                return true;

            // check for other combination
            str = arr[j] + arr[i];
            if (isPalindrome(str))
                return true;
        }
    }
    return false;
}

static void Main() {
    string[] arr = { "geekf", "geeks", "or", "keeg", "abc", "bc" };
    if (palindromePair(arr))
        Console.WriteLine("True");
    else
        Console.WriteLine("False");
}

}

JavaScript

// Function to check if a string is palindrome function isPalindrome(s) { let n = s.length;

// compare each character from starting
// with its corresponding character from last
for (let i = 0; i < Math.floor(n / 2); i++)
    if (s[i] !== s[n - i - 1])
        return false;

return true;

}

// Function to check if a palindrome pair exists function palindromePair(arr) {

// Consider each pair one by one
for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {

        // concatenate both strings
        let str = arr[i] + arr[j];

        // check if str is palindrome
        if (isPalindrome(str))
            return true;

        // check for other combination
        str = arr[j] + arr[i];
        if (isPalindrome(str))
            return true;
    }
}
return false;

}

// Driver code let arr = ["geekf", "geeks", "or", "keeg", "abc", "bc"]; if (palindromePair(arr)) console.log("True"); else console.log("False");

`

**Time Complexity: O(n2 * k), here n is the number of words in the array arr[] and k is the length of the longest concatenated string.
**Auxiliary Space:O(1)

[Expected Approach] Using Trie Data Structure - O(n * k^2) Time and O(n * k) Space

The idea is to use **Trie Data Structure to **store all the **strings and efficiently search for palindromic pairs. The intuition behind the Trie approach is to efficiently match each word with the reverse of another word to form a palindrome, without checking all pairs. We insert all words in reversed form into a Trie, while also storing information about prefixes that are palindromes. Then, for each word, we traverse the Trie to see if it can match with a reversed word such that the remaining part of the word forms a palindrome.

C++ `

#include <bits/stdc++.h> using namespace std;

// Trie node class TrieNode { public: // pointer array for 26 letters vector<TrieNode *> children;

// indices of palindromic words
vector<int> indices;

// index of word in array
int idx;

TrieNode() : idx(-1)
{

    // initialize children array to NULL
    children.resize(26, nullptr);
}

};

// Function to check if a string is palindrome bool isPalindrome(string str, int i, int j) {

// compare each character from starting
// with its corresponding character from last
while (i < j)
{
    if (str[i] != str[j])
        return false;
    i++, j--;
}
return true;

}

// If not present, inserts reverse of word into Trie. If // the word is prefix of a Trie node, just mark leaf node void insert(TrieNode *root, string word, int idx) { TrieNode *node = root;

// Start traversing word from the last
for (int i = word.length() - 1; i >= 0; i--)
{
    // If current word is palindrome till this
    // i, store index of current word.
    if (isPalindrome(word, 0, i))
        (node->indices).push_back(idx);

    // If it is not available in Trie
    // then store it
    int index = word[i] - 'a';
    if (!node->children[index])
        node->children[index] = new TrieNode();

    // move to new TrieNode
    node = node->children[index];
}
node->idx = idx;
node->indices.push_back(idx);

}

// Returns true if word presents in Trie, else false bool search(TrieNode *root, string word, int idx) { TrieNode *node = root; for (int i = 0; i < word.length() && node; i++) { int index = word[i] - 'a';

    // If it is present also check upto
    // which index it is palindrome
    if (node->idx >= 0 && node->idx != idx && isPalindrome(word, i, word.size() - 1))
        return true;

    node = node->children[index];
}

if (node)
{
    for (int i : node->indices)
    {
        if (idx != i)
            return true;
    }
}

return false;

}

// Function to check if a palindrome pair exists bool palindromePair(vector &arr) {

// Construct trie
TrieNode *root = new TrieNode();
for (int i = 0; i < arr.size(); i++)
    insert(root, arr[i], i);

// Search for different keys
for (int i = 0; i < arr.size(); i++)
{
    if (search(root, arr[i], i))
        return true;
}
return false;

}

int main() { vector arr = {"geekf", "geeks", "or", "keeg", "abc", "bc"}; if (palindromePair(arr)) cout << "True"; else cout << "False"; return 0; }

Java

import java.util.*;

class TrieNode {

// pointer array for 26 letters
TrieNode[] children;

// indices of palindromic words
List<Integer> indices;

// index of word in array
int idx;

TrieNode() {
    this.idx = -1;

    // initialize children array to NULL
    this.children = new TrieNode[26];
    this.indices = new ArrayList<>();
}

}

class GFG {

// Function to check if a string is palindrome
static boolean isPalindrome(String str, int i, int j) {

    // compare each character from starting
    // with its corresponding character from last
    while (i < j) {
        if (str.charAt(i) != str.charAt(j))
            return false;
        i++; j--;
    }
    return true;
}

// If not present, inserts reverse of word into Trie.
// If the word is prefix of a Trie node, just mark leaf node
static void insert(TrieNode root, String word, int idx) {
    TrieNode node = root;

    // Start traversing word from the last
    for (int i = word.length() - 1; i >= 0; i--) {
        // If current word is palindrome till this
        // i, store index of current word.
        if (isPalindrome(word, 0, i))
            node.indices.add(idx);
        
        // If it is not available in Trie
        // then store it
        int index = word.charAt(i) - 'a';
        if (node.children[index] == null)
            node.children[index] = new TrieNode();

        // move to new TrieNode
        node = node.children[index];
    }
    node.idx = idx;
    node.indices.add(idx);
}

// Returns true if word presents in Trie, else false
static boolean search(TrieNode root, String word, int idx) {
    TrieNode node = root;
    for (int i = 0; i < word.length() && node != null; i++) {
        int index = word.charAt(i) - 'a';

        // If it is present also check upto 
        // which index it is palindrome
        if (node.idx >= 0 && node.idx != idx &&
            isPalindrome(word, i, word.length()-1))
                return true;

        node = node.children[index];
    }

    if (node != null) {
        for (int i : node.indices) {
            if (idx != i)
                return true;
        }
    }

    return false;
}

// Function to check if a palindrome pair exists
static boolean palindromePair(String[] arr) {

    // Construct trie
    TrieNode root = new TrieNode();
    for (int i = 0; i < arr.length; i++)
        insert(root, arr[i], i);

    // Search for different keys
    for (int i = 0; i < arr.length; i++) {
        if (search(root, arr[i], i))
            return true;
    }
    return false;
}

public static void main(String[] args) {
    String[] arr = {"geekf", "geeks", "or", "keeg", "abc", "bc"};
    if (palindromePair(arr))
        System.out.println("True");
    else
        System.out.println("False");
}

}

Python

Trie node

class TrieNode:

def __init__(self):
    # pointer array for 26 letters
    self.children = [None] * 26

    # indices of palindromic words
    self.indices = []

    # index of word in array
    self.idx = -1

Function to check if a string is palindrome

def isPalindrome(word, i, j):

# compare each character from starting
# with its corresponding character from last
while i < j:
    if word[i] != word[j]:
        return False
    i += 1
    j -= 1
return True

If not present, inserts reverse of word into Trie.

If the word is prefix of a Trie node, just mark leaf node

def insert(root, word, idx): node = root

# Start traversing word from the last
for i in range(len(word) - 1, -1, -1):
    # If current word is palindrome till this
    # i, store index of current word.
    if isPalindrome(word, 0, i):
        node.indices.append(idx)

    index = ord(word[i]) - ord('a')
    if not node.children[index]:
        node.children[index] = TrieNode()

    node = node.children[index]

node.idx = idx
node.indices.append(idx)

Returns true if word presents in Trie, else false

def search(root, word, idx): node = root for i in range(len(word)): index = ord(word[i]) - ord('a')

    # If it is present also check up to 
    # which index it is palindrome
    if node.idx >= 0 and node.idx != idx and \
        isPalindrome(word, i, len(word) - 1):
        return True

    if not node.children[index]:
        return False

    node = node.children[index]

return any(i != idx for i in node.indices)

Function to check if a palindrome pair exists

def palindromePair(arr): root = TrieNode()

# Construct trie
for i in range(len(arr)):
    insert(root, arr[i], i)

# Search for different keys
for i in range(len(arr)):
    if search(root, arr[i], i):
        return True
return False

Driver code

if name == "main": arr = ["geekf", "geeks", "or", "keeg", "abc", "bc"] if palindromePair(arr): print("True") else: print("False")

C#

using System; using System.Collections.Generic;

class TrieNode {

// pointer array for 26 letters
public TrieNode[] children;

// indices of palindromic words
public List<int> indices;

// index of word in array
public int idx;

public TrieNode() {
    // initialize children array to null
    children = new TrieNode[26];
    indices = new List<int>();
    idx = -1;
}

}

class GFG {

// Function to check if a string is palindrome
static bool isPalindrome(string word, int i, int j) {

    // compare each character from starting
    // with its corresponding character from last
    while (i < j) {
        if (word[i] != word[j])
            return false;
        i++; j--;
    }
    return true;
}

// If not present, inserts reverse of word into Trie. 
// If the word is prefix of a Trie node, just mark leaf node
static void insert(TrieNode root, string word, int idx) {
    TrieNode node = root;

    // Start traversing word from the last
    for (int i = word.Length - 1; i >= 0; i--) {
        // If current word is palindrome till this
        // i, store index of current word.
        if (isPalindrome(word, 0, i))
            node.indices.Add(idx);

        // If it is not available in Trie
        // then store it
        int index = word[i] - 'a';
        if (node.children[index] == null)
            node.children[index] = new TrieNode();

        // move to new TrieNode
        node = node.children[index];
    }
    node.idx = idx;
    node.indices.Add(idx);
}

// Returns true if word presents in Trie, else false
static bool search(TrieNode root, string word, int idx) {
    TrieNode node = root;
    for (int i = 0; i < word.Length && node != null; i++) {
        int index = word[i] - 'a';

        // If it is present also check up to 
        // which index it is palindrome
        if (node.idx >= 0 && node.idx != idx &&
            isPalindrome(word, i, word.Length - 1))
                return true;

        node = node.children[index];
    }

    if (node != null) {
        foreach (int i in node.indices) {
            if (idx != i)
                return true;
        }
    }

    return false;
}

// Function to check if a palindrome pair exists
static bool palindromePair(string[] arr) {

    // Construct trie
    TrieNode root = new TrieNode();
    for (int i = 0; i < arr.Length; i++)
        insert(root, arr[i], i);

    // Search for different keys
    for (int i = 0; i < arr.Length; i++) {
        if (search(root, arr[i], i))
            return true;
    }
    return false;
}

static void Main() {
    string[] arr = { "geekf", "geeks", "or", "keeg", "abc", "bc" };
    if (palindromePair(arr))
        Console.WriteLine("True");
    else
        Console.WriteLine("False");
}

}

JavaScript

class TrieNode {

constructor() {
    // pointer array for 26 letters
    this.children = new Array(26).fill(null);
    
    // indices of palindromic words
    this.indices = [];

    // index of word in array
    this.idx = -1;
}

}

// Function to check if a string is palindrome function isPalindrome(word, i, j) {

// compare each character from starting
// with its corresponding character from last
while (i < j) {
    if (word[i] !== word[j])
        return false;
    i++; j--;
}
return true;

}

// If not present, inserts reverse of word into Trie. // If the word is prefix of a Trie node, just mark leaf node function insert(root, word, idx) { let node = root;

// Start traversing word from the last
for (let i = word.length - 1; i >= 0; i--) {
    // If current word is palindrome till this
    // i, store index of current word.
    if (isPalindrome(word, 0, i))
        node.indices.push(idx);
    
    // If it is not available in Trie
    // then store it
    let index = word.charCodeAt(i) - 'a'.charCodeAt(0);
    if (!node.children[index])
        node.children[index] = new TrieNode();

    // move to new TrieNode
    node = node.children[index];
}
node.idx = idx;
node.indices.push(idx);

}

// Returns true if word presents in Trie, else false function search(root, word, idx) { let node = root; for (let i = 0; i < word.length && node; i++) { let index = word.charCodeAt(i) - 'a'.charCodeAt(0);

    // If it is present also check upto 
    // which index it is palindrome
    if (node.idx >= 0 && node.idx !== idx &&
        isPalindrome(word, i, word.length - 1))
            return true;

    node = node.children[index];
}

if (node) {
    for (let i of node.indices) {
        if (idx !== i)
            return true;
    }
}

return false;

}

// Function to check if a palindrome pair exists function palindromePair(arr) {

// Construct trie
let root = new TrieNode();
for (let i = 0; i < arr.length; i++)
    insert(root, arr[i], i);

// Search for different keys
for (let i = 0; i < arr.length; i++) {
    if (search(root, arr[i], i))
        return true;
}
return false;

}

// Driver code let arr = ["geekf", "geeks", "or", "keeg", "abc", "bc"]; if (palindromePair(arr)) console.log("True"); else console.log("False");

`

[Alternate Approach] Using HashMap - O(n * k^2) Time and O(n * k) Space

The above approach can also be implemented using **HashMap instead of Trie. The intuition behind this approach is to break each word into two parts (a prefix and a suffix) and try to form a palindrome by pairing it with another word. For every split, we check two cases: if the prefix is a palindrome, then we look for the reverse of the suffix in the array; and if the suffix is a palindrome, we look for the reverse of the prefix. If such a matching word exists, combining them will form a palindrome.

Dry run for arr = ["geekf", "geeks", "keeg"]:

Final answer : True

C++ `

#include <bits/stdc++.h> using namespace std;

// Function to check if a string is palindrome bool isPalindrome(string &s) { int n = s.length();

// compare each character from starting
// with its corresponding character from last
for (int i = 0; i < n / 2; i++)
    if (s[i] != s[n - i - 1])
        return false;

return true;

}

// Function to check if a palindrome pair exists bool palindromePair(vector &arr) {

// to store all substrings of all words
// along with indices in reverse order
unordered_map<string, int> str;

// to store all reverse of all words
for (int i = 0; i < arr.size(); i++)
{
    string word = arr[i];
    reverse(word.begin(), word.end());
    str[word] = i;
}

// enumerating over all words and
// for each character of them
for (int i = 0; i < arr.size(); i++)
{

    // to store the left substring of arr[i]
    string left = "";

    for (int j = 0; j < arr[i].size(); j++)
    {

        // add currrent character to word
        left += arr[i][j];

        // extract right substring
        string right = arr[i].substr(j + 1);

        // if word is not empty and is palindrome
        // and right is present in the map
        if (!left.empty() && isPalindrome(left) && str.count(right) && str[right] != i)
            return true;

        // check the same by swapping word and right
        if (isPalindrome(right) && str.count(left) && str[left] != i)
            return true;
    }
}
return false;

}

int main() { vector arr = {"geekf", "geeks", "or", "keeg", "abc", "bc"}; if (palindromePair(arr)) cout << "True"; else cout << "False"; return 0; }

Java

import java.util.*;

class GFG {

// Function to check if a string is palindrome
static boolean isPalindrome(String s)
{
    int n = s.length();

    // compare each character from starting
    // with its corresponding character from last
    for (int i = 0; i < n / 2; i++)
        if (s.charAt(i) != s.charAt(n - i - 1))
            return false;

    return true;
}

// Function to check if a palindrome pair exists
static boolean palindromePair(String[] arr)
{

    // to store all substrings of all words
    // along with indices in reverse order
    Map<String, Integer> str = new HashMap<>();

    // to store all reverse of all words
    for (int i = 0; i < arr.length; i++) {
        String word = new StringBuilder(arr[i])
                          .reverse()
                          .toString();
        str.put(word, i);
    }

    // enumerating over all words and
    // for each character of them
    for (int i = 0; i < arr.length; i++) {

        // to store the left substring of arr[i]
        String left = "";

        for (int j = 0; j < arr[i].length(); j++) {

            // add current character to word
            left += arr[i].charAt(j);

            // extract right substring
            String right = arr[i].substring(j + 1);

            // if word is not empty and is palindrome
            // and right is present in the map
            if (!left.isEmpty() && isPalindrome(left)
                && str.containsKey(right)
                && str.get(right) != i)
                return true;

            // check the same by swapping word and right
            if (isPalindrome(right)
                && str.containsKey(left)
                && str.get(left) != i)
                return true;
        }
    }
    return false;
}

public static void main(String[] args)
{
    String[] arr = { "geekf", "geeks", "or",
                     "keeg",  "abc",   "bc" };
    if (palindromePair(arr))
        System.out.println("True");
    else
        System.out.println("False");
}

}

Python

Function to check if a string is palindrome

def isPalindrome(s): n = len(s)

# compare each character from starting
# with its corresponding character from last
for i in range(n // 2):
    if s[i] != s[n - i - 1]:
        return False

return True

Function to check if a palindrome pair exists

def palindromePair(arr):

# to store all substrings of all words
# along with indices in reverse order
strMap = {}

# to store all reverse of all words
for i in range(len(arr)):
    word = arr[i][::-1]
    strMap[word] = i

# enumerating over all words and
# for each character of them
for i in range(len(arr)):

    # to store the left substring of arr[i]
    left = ""

    for j in range(len(arr[i])):

        # add current character to word
        left += arr[i][j]

        # extract right substring
        right = arr[i][j + 1:]

        # if word is not empty and is palindrome
        # and right is present in the map
        if left and isPalindrome(left) and \
                right in strMap and strMap[right] != i:
            return True

        # check the same by swapping word and right
        if isPalindrome(right) and \
                left in strMap and strMap[left] != i:
            return True

return False

Driver code

if name == "main": arr = ["geekf", "geeks", "or", "keeg", "abc", "bc"] if palindromePair(arr): print("True") else: print("False")

C#

using System; using System.Collections.Generic;

class GFG {

// Function to check if a string is palindrome
static bool isPalindrome(string s)
{
    int n = s.Length;

    // compare each character from starting
    // with its corresponding character from last
    for (int i = 0; i < n / 2; i++)
        if (s[i] != s[n - i - 1])
            return false;

    return true;
}

// Function to check if a palindrome pair exists
static bool palindromePair(string[] arr)
{

    // to store all substrings of all words
    // along with indices in reverse order
    Dictionary<string, int> str
        = new Dictionary<string, int>();

    // to store all reverse of all words
    for (int i = 0; i < arr.Length; i++) {
        char[] wordArr = arr[i].ToCharArray();
        Array.Reverse(wordArr);
        string word = new string(wordArr);
        str[word] = i;
    }

    // enumerating over all words and
    // for each character of them
    for (int i = 0; i < arr.Length; i++) {

        // to store the left substring of arr[i]
        string left = "";

        for (int j = 0; j < arr[i].Length; j++) {

            // add current character to word
            left += arr[i][j];

            // extract right substring
            string right = arr[i].Substring(j + 1);

            // if word is not empty and is palindrome
            // and right is present in the map
            if (!string.IsNullOrEmpty(left)
                && isPalindrome(left)
                && str.ContainsKey(right)
                && str[right] != i)
                return true;

            // check the same by swapping word and right
            if (isPalindrome(right)
                && str.ContainsKey(left)
                && str[left] != i)
                return true;
        }
    }
    return false;
}

public static void Main()
{
    string[] arr = { "geekf", "geeks", "or",
                     "keeg",  "abc",   "bc" };
    if (palindromePair(arr))
        Console.WriteLine("True");
    else
        Console.WriteLine("False");
}

}

JavaScript

// Function to check if a string is palindrome function isPalindrome(s) { let n = s.length;

// compare each character from starting
// with its corresponding character from last
for (let i = 0; i < Math.floor(n / 2); i++)
    if (s[i] !== s[n - i - 1])
        return false;

return true;

}

// Function to check if a palindrome pair exists function palindromePair(arr) {

// to store all substrings of all words
// along with indices in reverse order
let str = new Map();

// to store all reverse of all words
for (let i = 0; i < arr.length; i++) {
    let word = arr[i].split("").reverse().join("");
    str.set(word, i);
}

// enumerating over all words and
// for each character of them
for (let i = 0; i < arr.length; i++) {

    // to store the left substring of arr[i]
    let left = "";

    for (let j = 0; j < arr[i].length; j++) {

        // add current character to word
        left += arr[i][j];

        // extract right substring
        let right = arr[i].substring(j + 1);

        // check palindrome conditions
        if (left && isPalindrome(left) && str.has(right)
            && str.get(right) !== i)
            return true;

        if (isPalindrome(right) && str.has(left)
            && str.get(left) !== i)
            return true;
    }
}
return false;

}

// Driver code let arr = [ "geekf", "geeks", "or", "keeg", "abc", "bc" ]; console.log(palindromePair(arr) ? "True" : "False");

`