Minimum insertions to form a palindrome with permutations allowed
Given a string of lowercase letters. Find minimum characters to be inserted in the string so that it can become palindrome. We can change the positions of characters in the string.
Examples:
Input: geeksforgeeks
Output: 2
Explanation: geeksforgeeks can be changed as: geeksroforskeeg or geeksorfroskeeg and many more using two insertion.
Input: aabbc
Output: 0
Explanation: aabbc can be changed as: abcba or bacab without any insertion
Table of Content
[Expected Approach] Character Frequency Counting - O(n) Time and O(1) Space
To make a string palindromic, count the occurrences of each character. A palindrome can have at most one character with an odd frequency; the rest must occur an even number of times. The minimum insertions required are one less than the count of characters with odd frequencies. If the string is already a palindrome, no insertions are needed (result = 0).
#include <bits/stdc++.h>
using namespace std;
int minInsertion(string &str)
{
int n = str.length();
int res = 0;
vector<int> count(26,0);
for (int i = 0; i < n; i++)
count[str[i] - 'a']++;
for (int i = 0; i < 26; i++)
if (count[i] % 2 == 1)
res++;
return (res == 0) ? 0 : res - 1;
}
// Driver program
int main()
{
string str = "geeksforgeeks";
cout << minInsertion(str);
return 0;
}
public class GfG {
static int minInsertion(String str)
{
int n = str.length();
int res = 0;
int[] count = new int[26];
for (int i = 0; i < n; i++)
count[str.charAt(i) - 'a']++;
for (int i = 0; i < 26; i++) {
if (count[i] % 2 == 1)
res++;
}
return (res == 0) ? 0 : res - 1;
}
// Driver program
public static void main(String[] args)
{
String str = "geeksforgeeks";
System.out.println(minInsertion(str));
}
}
import math as mt
def minInsertion(tr1):
n = len(str1)
res = 0
count = [0 for i in range(26)]
for i in range(n):
count[ord(str1[i]) - ord('a')] += 1
for i in range(26):
if (count[i] % 2 == 1):
res += 1
if (res == 0):
return 0
else:
return res - 1
# Driver Code
str1 = "geeksforgeeks"
print(minInsertion(str1))
using System;
public class GfG {
static int minInsertion(String str)
{
int n = str.Length;
int res = 0;
int[] count = new int[26];
for (int i = 0; i < n; i++)
count[str[i] - 'a']++;
for (int i = 0; i < 26; i++) {
if (count[i] % 2 == 1)
res++;
}
return (res == 0) ? 0 : res - 1;
}
// Driver program
public static void Main()
{
string str = "geeksforgeeks";
Console.WriteLine(minInsertion(str));
}
}
function minInsertion(str)
{
let n = str.length;
let res = 0;
let count = new Array(26);
for (let i = 0; i < count.length; i++) {
count[i] = 0;
}
for (let i = 0; i < n; i++)
count[str[i].charCodeAt(0) - "a".charCodeAt(0)]++;
for (let i = 0; i < 26; i++) {
if (count[i] % 2 == 1)
res++;
}
return (res == 0) ? 0 : res - 1;
}
let str = "geeksforgeeks";
console.log(minInsertion(str));
Output
2
[Alternate Approach] using Bit manipulation - O(n) Time and O(1) Space
Initialize a mask to
0
and toggle bits for each character based on its position in the alphabet. If the mask becomes0
, the string is already a palindrome (return 0). Otherwise, the minimum insertions required are the number of set bits in the mask minus one.
#include <bits/stdc++.h>
using namespace std;
int minInsertion(string &str)
{
long long mask = 0;
for (auto c : str)
mask ^= (1 << (c - 'a'));
if (mask == 0)
return 0;
int count = 0;
while (mask) {
count += mask & 1;
mask = mask >> 1;
}
return count - 1;
}
// Driver program
int main()
{
string str = "geeksforgeeks";
cout << minInsertion(str);
return 0;
}
// This code is contributed by hkdass001
import java.util.*;
public class GfG {
static int minInsertion(String str)
{
long mask = 0;
for (char c : str.toCharArray())
mask ^= (1 << (c - 'a'));
if (mask == 0)
return 0;
int count = 0;
while (mask != 0) {
count += mask & 1;
mask = mask >> 1;
}
return count - 1;
}
// Driver program
public static void main(String[] args)
{
String str = "geeksforgeeks";
System.out.println(minInsertion(str));
}
}
// This code is contributed by Karandeep1234
def minInsertion(str):
mask = 0
for c in str:
mask ^= (1 << (ord(c) - ord('a')))
if mask == 0:
return 0
count = 0
while mask:
count += mask & 1
mask = mask >> 1
return count - 1
str = "geeksforgeeks"
print(minInsertion(str))
using System;
using System.Collections.Generic;
class GfG
{
static int minInsertion(string str)
{
int mask = 0;
foreach(char c in str)
mask ^= (1 << (c - 'a'));
if (mask == 0)
return 0;
int count = 0;
while (mask>0) {
count += mask & 1;
mask = mask >> 1;
}
return count - 1;
}
// Driver program
static void Main(string[] args)
{
string str = "geeksforgeeks";
Console.Write(minInsertion(str));
}
}
function minInsertion(str) {
let mask = 0;
for (let c of str) {
mask ^= (1 << (c.charCodeAt(0) - 'a'.charCodeAt(0)));
}
if (mask === 0) {
return 0;
}
let count = 0;
while (mask) {
count += mask & 1;
mask = mask >> 1;
}
// return the count minus 1
return count - 1;
}
// Driver program
let str = "geeksforgeeks";
console.log(minInsertion(str));
Output
2