Open In App

Check if string can be rearranged so that every Odd length Substring is Palindrome

Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S. The task is to check whether it is possible to rearrange the string such that every substring of odd length is a palindrome.

Examples: 

Input: S = "oiooi" 
Output: YES 
The string can be rearranged as "oioio"
Input: S = "yuyuo" 
Output: NO 

Approach:  

  • The very first observation is if all the characters of the string are the same then every substring of odd length is a palindrome, and we do not need to rearrange them.
  • The second observation is if the number of distinct characters is more than 2 then it is impossible to rearrange.
  • Now if the number of distinct characters are exactly 2 then to get all odd length substring to be a palindrome, the difference of their count must be less than or equal to 1, and if this satisfies then we rearrange the string in an alternate manner means

s_{i-1}=s_{i+1}

  • for i <— ( 1 to n – 1 ). Where n is the length of the string.


Below is the implementation of the above approach: 
 

C++

// C++ implementation of
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check is it
// possible to rearrange the string
// such that every odd length
// substring is palindrome
bool IsPossible(string s)
{
 
    // Length of the string
    int n = s.length();
 
    // To count number of distinct
    // character in string
    set<char> count;
 
    // To count frequency of
    // each character
    map<char, int> map;
 
    for (int i = 0; i < n; i++) {
 
        // Inserting into set
        count.insert(s[i]);
 
        // Incrementing the frequency
        map[s[i]] += 1;
    }
 
    // All characters in
    // the string are same
    if (count.size() == 1) {
        return true;
    }
 
    // There are more than 2 different
    // character in string
    if (count.size() > 2) {
        return false;
    }
 
    // Currently there is 2 different
    // character in string
    auto it = count.begin();
 
    // Get the frequencies of the
    // characters that present
    // in string
    int x = 0, y = 0;
    x = map[*it];
 
    it++;
    y = map[*it];
 
    // Difference between their
    // count is less than or
    // equal to 1
    if (abs(x - y) <= 1) {
        return true;
    }
 
    return false;
}
 
// Driver code
int main()
{
    string s = "aaaddad";
 
    if (IsPossible(s))
        cout << "YES\n";
    else
        cout << "NO\n";
 
    return 0;
}

                    

Java

// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    // Function to check is it
    // possible to rearrange the string
    // such that every odd length
    // substring is palindrome
    static boolean IsPossible(String s)
    {
 
        // Length of the string
        int n = s.length();
 
        // To count number of distinct
        // character in string
        HashSet<Character> count = new HashSet<>();
 
        // To count frequency of
        // each character
        HashMap<Character, Integer> map = new HashMap<>();
 
        for (int i = 0; i < n; i++)
        {
 
            // Inserting into set
            count.add(s.charAt(i));
 
            // Incrementing the frequency
            map.put(s.charAt(i), map.get(s.charAt(i)) ==
                    null ? 1 : map.get(s.charAt(i)) + 1);
        }
 
        // All characters in
        // the string are same
        if (count.size() == 1)
            return true;
 
        // There are more than 2 different
        // character in string
        if (count.size() > 2)
            return false;
 
        String newString = count.toArray().toString();
 
        // Currently there is 2 different
        // character in string
        int j = 0;
        char it = newString.charAt(j);
 
        // Get the frequencies of the
        // characters that present
        // in string
        int x = 0, y = 0;
        x = map.get(it) == null ? 0 : map.get(it);
        j++;
 
        it = newString.charAt(j);
        y = map.get(it) == null ? 0 : map.get(it);
 
        // Difference between their
        // count is less than or
        // equal to 1
        if (Math.abs(x - y) <= 1)
            return true;
        return false;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String s = "aaaddad";
        if (IsPossible(s))
            System.out.println("YES");
        else
            System.out.println("NO");
    }
}
 
// This code is contributed by
// sanjeev2552

                    

Python3

# Python3 implementation of
# the above approach
 
# Function to check is it
# possible to rearrange the string
# such that every odd length
# substring is palindrome
def IsPossible(s) :
 
    # Length of the string
    n = len(s);
 
    # To count number of distinct
    # character in string
    count = set();
     
    # To count frequency of
    # each character
    map = dict.fromkeys(s, 0);
 
    for i in range(n) :
 
        # Inserting into set
        count.add(s[i]);
 
        # Incrementing the frequency
        map[s[i]] += 1;
 
    # All characters in
    # the string are same
    if (len(count) == 1) :
        return True;
 
    # There are more than 2 different
    # character in string
    if (len(count) > 2) :
        return False;
         
    # Currently there is 2 different
    # character in string
    j = 0
    it = list(count)[j];
 
    # Get the frequencies of the
    # characters that present
    # in string
    x = 0; y = 0;
    x = map[it];
     
    j += 1
    it = list(count)[j];
    y = map[it];
 
    # Difference between their
    # count is less than or
    # equal to 1
    if (abs(x - y) <= 1) :
        return True;
 
    return False;
 
# Driver code
if __name__ == "__main__" :
 
    s = "aaaddad";
 
    if (IsPossible(s)) :
        print("YES");
    else :
        print("NO");
         
# This code is contributed by AnkitRai01

                    

C#

// C# implementation of the
// above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to check is it
// possible to rearrange the string
// such that every odd length
// substring is palindrome
static bool IsPossible(String s)
{
 
  // Length of the string
  int n = s.Length;
 
  // To count number of distinct
  // character in string
  HashSet<char> count =
          new HashSet<char>();
 
  // To count frequency of
  // each character
  Dictionary<char,
             int> map = new Dictionary<char,
                                       int>();
 
  for (int i = 0; i < n; i++)
  {
    // Inserting into set
    count.Add(s[i]);
 
    // Incrementing the frequency
    if(map.ContainsKey(s[i]))
      map[s[i]] = map[s[i]] + 1;
    else
      map.Add(s[i], 1);
  }
 
  // All characters in
  // the string are same
  if (count.Count == 1)
    return true;
 
  // There are more than 2 different
  // character in string
  if (count.Count > 2)
    return false;
 
  String newString = count.ToString();
 
  // Currently there is 2 different
  // character in string
  int j = 0;
  char it = newString[j];
 
  // Get the frequencies of the
  // characters that present
  // in string
  int x = 0, y = 0;
  x = !map.ContainsKey(it) ?
       0 : map[it];
  j++;
 
  it = newString[j];
  y = !map.ContainsKey(it) ?
       0 : map[it];
 
  // Difference between their
  // count is less than or
  // equal to 1
  if (Math.Abs(x - y) <= 1)
    return true;
  return false;
}
 
// Driver Code
public static void Main(String[] args)
{
  String s = "aaaddad";
  if (IsPossible(s))
    Console.WriteLine("YES");
  else
    Console.WriteLine("NO");
}
}
 
// This code is contributed by 29AjayKumar

                    

Javascript

function IsPossible(s) {
    // Length of the string
    let n = s.length;
 
    // To count number of distinct
    // character in string
    let count = new Set();
 
    // To count frequency of
    // each character
    let map = new Map();
 
    for (let i = 0; i < n; i++) {
        // Inserting into set
        count.add(s[i]);
 
        // Incrementing the frequency
        if (map.has(s[i])) {
            map.set(s[i], map.get(s[i]) + 1);
        } else {
            map.set(s[i], 1);
        }
    }
 
    // All characters in
    // the string are same
    if (count.size === 1) return true;
 
    // There are more than 2 different
    // character in string
    if (count.size > 2) return false;
 
    let newArray = [...count];
 
    // Currently there is 2 different
    // character in string
    for (let it of newArray) {
        // Get the frequencies of the
        // characters that present
        // in string
        let x = 0, y = 0;
        x = map.get(it) || 0;
 
        // get the other character
        let it2 = newArray.find(c => c !== it);
        y = map.get(it2) || 0;
 
        // Difference between their
        // count is less than or
        // equal to 1
        if (Math.abs(x - y) <= 1) return true;
    }
    return false;
}
 
// Driver Code
let s = "aaaddad";
if (IsPossible(s)) {
    console.log("YES");
} else {
    console.log("NO");
}
// contributed by dany

                    

Output: 
YES

 

Time Complexity: O(n) ,where n is length of given string

Auxiliary Space: O(n)



Last Updated : 06 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads