Open In App

Form minimum number of Palindromic Strings from a given string

Last Updated : 26 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S, the task is to divide the characters of S to form minimum number of palindromic strings.

Note: There can be multiple correct answers.

Examples: 

Input: S = “geeksforgeeks”
Output: {eegksrskgee, o, f}

Explanation: 
There should be at least 3 strings “eegksrskgee”, “o”, “f”. All 3 formed strings are palindrome.

Input: S = “abbaa”
Output: {“ababa”}

Explanation:
The given string S = “ababa” is already a palindrome string so, only 1 string will be formed.

Input: S = “abc”
Output: {“a”, “b”, “c”}

Explanation: 
There should be at least 3 strings “a”, “b”, “c”. All 3 formed strings are palindrome.

Approach: 

The main observation is that a palindrome string remains the same if reversed. The length of the strings formed does not matter so try to make a string as large as possible. If some character can’t be a part of palindromic string, then push this character into a new string. 

  • The general approach would be to store the frequency of each character and if for some character the frequency is odd then we have to make a new string and increment our answer by 1.
  • Note that if there are no characters with odd frequency, at least one string is still needed, so the final answer will be max(1, odd frequency characters).
  • To print the string store odd characters frequency characters in a vector and even characters in another vector.
  • Form one palindromic string with strings having odd characters and append a string with an even number of characters and all other strings will be of only one character. 

Below is the implementation of the above approach:

C++




// C++ Program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to return
// minimum palindromic strings formed
int minimumPalindromicStrings(string S)
{
    // Store the length of string
    int N = S.length();
 
    // Iterate over the string
    // and store the frequency of
    // all characters A vector
    // to store the frequency
    vector<int> freq(26);
    for (int i = 0; i < N; i++) {
        freq[S[i] - 'a']++;
    }
 
    // Store the odd frequency characters
    vector<int> oddFreqCharacters;
 
    // Store the even frequency of characters
    // in the same vector by dividing
    // current frequency by 2 as one element
    // will be used on left as well as right side
 
    // Iterate through all possible characters
    // and check the parity of frequency
    for (int i = 0; i < 26; i++) {
 
        if (freq[i] & 1) {
 
            oddFreqCharacters.push_back(i);
            freq[i]--;
        }
 
        freq[i] /= 2;
    }
 
    // store answer in a vector
    vector<string> ans;
 
    // if there are no odd Frequency characters
    // then print the string with even characters
    if (oddFreqCharacters.empty()) {
 
        // store the left part
        // of the palindromic string
        string left = "";
 
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < freq[i]; j++) {
 
                left += char(i + 'a');
            }
        }
 
        string right = left;
 
        // reverse the right part of the string
        reverse(right.begin(), right.end());
 
        // store the string in ans vector
        ans.push_back(left + right);
    }
 
    else {
 
        // take any character
        // from off frequency element
        string middle = "";
        int c = oddFreqCharacters.back();
        oddFreqCharacters.pop_back();
        middle += char(c + 'a');
 
        // repeat the above step to form
        // left and right strings
        string left = "";
 
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < freq[i]; j++) {
 
                left += char(i + 'a');
            }
        }
 
        string right = left;
 
        // reverse the right part of the string
        reverse(right.begin(), right.end());
 
        // store the string in ans vector
        ans.push_back(left + middle + right);
 
        // store all other odd frequency strings
        while (!oddFreqCharacters.empty()) {
 
            int c = oddFreqCharacters.back();
            oddFreqCharacters.pop_back();
            string middle = "";
            middle += char(c + 'a');
            ans.push_back(middle);
        }
    }
 
    // Print the answer
    cout << "[";
    for (int i = 0; i < ans.size(); i++) {
        cout << ans[i];
        if (i != ans.size() - 1) {
            cout << ", ";
        }
    }
    cout << "]";
    return 0;
}
 
// Driver Code
int main()
{
    string S = "geeksforgeeks";
    minimumPalindromicStrings(S);
}


Java




// Java Program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to return
// minimum palindromic Strings formed
static int minimumPalindromicStrings(String S)
{
   
    // Store the length of String
    int N = S.length();
 
    // Iterate over the String
    // and store the frequency of
    // all characters A vector
    // to store the frequency
   int[] freq = new int[26];
    for (int i = 0; i < N; i++) {
        freq[S.charAt(i) - 'a']++;
    }
 
    // Store the odd frequency characters
    Vector<Integer> oddFreqCharacters = new Vector<Integer>();
 
    // Store the even frequency of characters
    // in the same vector by dividing
    // current frequency by 2 as one element
    // will be used on left as well as right side
 
    // Iterate through all possible characters
    // and check the parity of frequency
    for (int i = 0; i < 26; i++) {
 
        if (freq[i] % 2 == 1) {
 
            oddFreqCharacters.add(i);
            freq[i]--;
        }
 
        freq[i] /= 2;
    }
 
    // store answer in a vector
    Vector<String> ans = new Vector<String>();
 
    // if there are no odd Frequency characters
    // then print the String with even characters
    if (oddFreqCharacters.isEmpty()) {
 
        // store the left part
        // of the palindromic String
        String left = "";
 
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < freq[i]; j++) {
 
                left += (char)(i + 'a');
            }
        }
 
        String right = left;
 
        // reverse the right part of the String
        right = reverse(right);
 
        // store the String in ans vector
        ans.add(left + right);
    }
 
    else {
 
        // take any character
        // from off frequency element
        String middle = "";
        int c = oddFreqCharacters.lastElement();
        oddFreqCharacters.remove(oddFreqCharacters.size()-1);
        middle += (char)(c + 'a');
 
        // repeat the above step to form
        // left and right Strings
        String left = "";
 
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < freq[i]; j++) {
 
                left += (char)(i + 'a');
            }
        }
 
        String right = left;
 
        // reverse the right part of the String
        right = reverse(right);
 
        // store the String in ans vector
        ans.add(left + middle + right);
 
        // store all other odd frequency Strings
        while (!oddFreqCharacters.isEmpty()) {
 
            c = oddFreqCharacters.lastElement();
            oddFreqCharacters.remove(oddFreqCharacters.size()-1);
            middle = "";
            middle += (char)(c + 'a');
            ans.add(middle);
        }
    }
 
    // Print the answer
    System.out.print("[");
    for (int i = 0; i < ans.size(); i++) {
        System.out.print(ans.get(i));
        if (i != ans.size() - 1) {
            System.out.print(", ");
        }
    }
    System.out.print("]");
    return 0;
}
static String reverse(String input) {
    char[] a = input.toCharArray();
    int l, r = a.length - 1;
    for (l = 0; l < r; l++, r--) {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return String.valueOf(a);
}
   
// Driver Code
public static void main(String[] args)
{
    String S = "geeksforgeeks";
    minimumPalindromicStrings(S);
}
}
 
// This code is contributed by 29AjayKumar


Python3




def minimum_palindromic_strings(s):
    # Store the length of the string
    n = len(s)
 
    # Iterate over the string and store the frequency of all characters in a dictionary
    freq = {}
    for char in s:
        if char in freq:
            freq[char] += 1
        else:
            freq[char] = 1
 
    # Store the odd frequency characters
    odd_freq_characters = []
 
    # Store the even frequency of characters in the same dictionary
    # by dividing current frequency by 2
    # as one element will be used on the left as well as the right side
 
    # Iterate through all possible characters and check the parity of frequency
    for char in freq:
        if freq[char] % 2 == 1:
            odd_freq_characters.append(char)
            freq[char] -= 1
 
        freq[char] //= 2
 
    # Store answers in a list
    ans = []
 
    # If there are no odd frequency characters, then print the string with even characters
    if not odd_freq_characters:
        # Store the left part of the palindromic string
        left = ""
        for char in sorted(freq):
            left += char * freq[char]
 
        right = left[::-1# Reverse the right part of the string
 
        # Store the string in the ans list
        ans.append(left + right)
 
    else:
        # Take any character from off-frequency elements
        middle = odd_freq_characters.pop()
        middle = middle
 
        # Repeat the above step to form left and right strings
        left = ""
        for char in sorted(freq):
            left += char * freq[char]
 
        right = left[::-1# Reverse the right part of the string
 
        # Store the string in the ans list
        ans.append(left + middle + right)
 
        # Store all other odd frequency strings
        for char in odd_freq_characters:
            ans.append(char)
 
    # Print the answer
    print(ans)
 
# Driver Code
if __name__ == "__main__":
    S = "geeksforgeeks"
    minimum_palindromic_strings(S)


C#




// C# Program to implement
// the above approach
using System;
using System.Collections.Generic;
 
public class GFG{
 
// Function to return
// minimum palindromic Strings formed
static int minimumPalindromicStrings(String S)
{
   
    // Store the length of String
    int N = S.Length;
 
    // Iterate over the String
    // and store the frequency of
    // all characters A vector
    // to store the frequency
   int[] freq = new int[26];
    for (int i = 0; i < N; i++) {
        freq[S[i] - 'a']++;
    }
 
    // Store the odd frequency characters
    List<int> oddFreqchars = new List<int>();
 
    // Store the even frequency of characters
    // in the same vector by dividing
    // current frequency by 2 as one element
    // will be used on left as well as right side
 
    // Iterate through all possible characters
    // and check the parity of frequency
    for (int i = 0; i < 26; i++) {
 
        if (freq[i] % 2 == 1) {
 
            oddFreqchars.Add(i);
            freq[i]--;
        }
 
        freq[i] /= 2;
    }
 
    // store answer in a vector
    List<String> ans = new List<String>();
 
    // if there are no odd Frequency characters
    // then print the String with even characters
    if (oddFreqchars.Count==0) {
 
        // store the left part
        // of the palindromic String
        String left = "";
 
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < freq[i]; j++) {
 
                left += (char)(i + 'a');
            }
        }
 
        String right = left;
 
        // reverse the right part of the String
        right = reverse(right);
 
        // store the String in ans vector
        ans.Add(left + right);
    }
 
    else {
 
        // take any character
        // from off frequency element
        String middle = "";
        int c = oddFreqchars[oddFreqchars.Count-1];
        oddFreqchars.RemoveAt(oddFreqchars.Count-1);
        middle += (char)(c + 'a');
  
        // repeat the above step to form
        // left and right Strings
        String left = "";
 
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < freq[i]; j++) {
 
                left += (char)(i + 'a');
            }
        }
 
        String right = left;
 
        // reverse the right part of the String
        right = reverse(right);
 
        // store the String in ans vector
        ans.Add(left + middle + right);
 
        // store all other odd frequency Strings
        while (oddFreqchars.Count!=0) {
 
            c = oddFreqchars[oddFreqchars.Count-1];
            oddFreqchars.RemoveAt(oddFreqchars.Count-1);
            middle = "";
            middle += (char)(c + 'a');
            ans.Add(middle);
        }
    }
 
    // Print the answer
    Console.Write("[");
    for (int i = 0; i < ans.Count; i++) {
        Console.Write(ans[i]);
        if (i != ans.Count - 1) {
            Console.Write(", ");
        }
    }
    Console.Write("]");
    return 0;
}
static String reverse(String input) {
    char[] a = input.ToCharArray();
    int l, r = a.Length - 1;
    for (l = 0; l < r; l++, r--) {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return String.Join("",a);
}
   
// Driver Code
public static void Main(String[] args)
{
    String S = "geeksforgeeks";
    minimumPalindromicStrings(S);
}
}
 
  
 
// This code is contributed by 29AjayKumar


Javascript




function minimumPalindromicStrings(S) {
    // Store the length of the string
    const N = S.length;
 
    // Iterate over the string and store the frequency of all characters in an array
    const freq = new Array(26).fill(0);
    for (let i = 0; i < N; i++) {
        freq[S.charCodeAt(i) - 'a'.charCodeAt(0)]++;
    }
 
    // Store the odd frequency characters
    const oddFreqCharacters = [];
 
    // Iterate through all possible characters and check the parity of frequency
    for (let i = 0; i < 26; i++) {
        if (freq[i] & 1) {
            oddFreqCharacters.push(i);
            freq[i]--;
        }
 
        freq[i] /= 2;
    }
 
    // Store answers in an array
    const ans = [];
 
    // If there are no odd frequency characters, then print the string with even characters
    if (oddFreqCharacters.length === 0) {
        // Store the left part of the palindromic string
        let left = "";
 
        for (let i = 0; i < 26; i++) {
            for (let j = 0; j < freq[i]; j++) {
                left += String.fromCharCode(i + 'a'.charCodeAt(0));
            }
        }
 
        const right = left.split("").reverse().join(""); // Reverse the right part of the string
 
        // Store the string in the ans array
        ans.push(left + right);
    } else {
        // Take any character from off-frequency elements
        let middle = "";
        const c = oddFreqCharacters.pop();
        middle += String.fromCharCode(c + 'a'.charCodeAt(0));
 
        // Repeat the above step to form left and right strings
        let left = "";
 
        for (let i = 0; i < 26; i++) {
            for (let j = 0; j < freq[i]; j++) {
                left += String.fromCharCode(i + 'a'.charCodeAt(0));
            }
        }
 
        const right = left.split("").reverse().join(""); // Reverse the right part of the string
 
        // Store the string in the ans array
        ans.push(left + middle + right);
 
        // Store all other odd frequency strings
        while (oddFreqCharacters.length > 0) {
            const c = oddFreqCharacters.pop();
            let middle = "";
            middle += String.fromCharCode(c + 'a'.charCodeAt(0));
            ans.push(middle);
        }
    }
 
    // Print the answer
    console.log(ans);
}
 
// Driver Code
const S = "geeksforgeeks";
minimumPalindromicStrings(S);


Output

[eegksrskgee, o, f]

Time Complexity: O(N*26)

Space Complexity: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads