Maximum length palindrome that can be created with characters in range L and R
Last Updated :
21 Jun, 2022
Given a string str and Q queries. Each query consists of two numbers L and R. The task is to find the maximum length palindrome that can be created with characters in the range [L, R].
Examples:
Input: str = “amim”, Q[] = {{1, 4}, {3, 4}
Output:
3
1
In range [1, 4], only two palindromes “mam” and “mim” can be formed.
In range [3, 4], only “i” or “m” can be created using the characters in range.
Input: str = “aaaaa”, Q[] = {{1, 5}, {5, 5}
Output:
5
1
Approach: Let prefix[i][j] be an array which denotes the frequency of character char(j+97) in range 1 to i. For any range L to R, count the even frequencies and the odd frequencies. Since odd-1 is even, it can also contribute to the palindromic string. Also keep a mark for an odd frequency character, which can be inserted in the middle. Hence the length of the longest palindrome possible will be the sum of all even and the sum of odd-1 frequencies, adding 1 if there exists an odd frequency character.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 4
int performQueries( int l, int r, int prefix[N][26])
{
l--;
r--;
bool flag = false ;
int count = 0;
for ( int i = 0; i < 26; i++) {
int cnt = prefix[r][i];
if (l > 0)
cnt -= prefix[l - 1][i];
if (cnt % 2 == 1) {
flag = true ;
count += cnt - 1;
}
else
count += cnt;
}
if (flag)
count += 1;
return count;
}
void preCalculate(string s, int prefix[N][26])
{
int n = s.size();
for ( int i = 0; i < n; i++) {
prefix[i][s[i] - 'a' ]++;
}
for ( int i = 1; i < n; i++) {
for ( int j = 0; j < 26; j++)
prefix[i][j] += prefix[i - 1][j];
}
}
int main()
{
string s = "amim" ;
int prefix[N][26];
memset (prefix, 0, sizeof prefix);
preCalculate(s, prefix);
int queries[][2] = { { 1, 4 }, { 3, 4 } };
int q = sizeof (queries) / sizeof (queries[0]);
for ( int i = 0; i < q; i++) {
cout << performQueries(queries[i][0],
queries[i][1], prefix)
<< endl;
}
return 0;
}
|
Java
class GFG
{
static int N = 4 ;
static int performQueries( int l, int r, int prefix[][])
{
l--;
r--;
boolean flag = false ;
int count = 0 ;
for ( int i = 0 ; i < 26 ; i++)
{
int cnt = prefix[r][i];
if (l > 0 )
cnt -= prefix[l - 1 ][i];
if (cnt % 2 == 1 )
{
flag = true ;
count += cnt - 1 ;
}
else
count += cnt;
}
if (flag)
count += 1 ;
return count;
}
static void preCalculate(String s, int prefix[][])
{
int n = s.length();
for ( int i = 0 ; i < n; i++)
{
prefix[i][s.charAt(i) - 'a' ]++;
}
for ( int i = 1 ; i < n; i++)
{
for ( int j = 0 ; j < 26 ; j++)
prefix[i][j] += prefix[i - 1 ][j];
}
}
public static void main(String args[])
{
String s = "amim" ;
int prefix[][] = new int [N][ 26 ];
preCalculate(s, prefix);
int queries[][] = { { 1 , 4 }, { 3 , 4 } };
int q = queries.length;
for ( int i = 0 ; i < q; i++)
{
System.out.println( performQueries(queries[i][ 0 ],
queries[i][ 1 ], prefix) );
}
}
}
|
Python3
N = 4
def performQueries(l, r, prefix):
l - = 1
r - = 1
flag = False
count = 0
for i in range ( 26 ):
cnt = prefix[r][i]
if (l > 0 ):
cnt - = prefix[l - 1 ][i]
if (cnt % 2 = = 1 ):
flag = True
count + = cnt - 1
else :
count + = cnt
if (flag):
count + = 1
return count
def preCalculate(s, prefix):
n = len (s)
for i in range (n):
prefix[i][ ord (s[i]) - ord ( 'a' )] + = 1
for i in range ( 1 , n):
for j in range ( 26 ):
prefix[i][j] + = prefix[i - 1 ][j]
s = "amim"
prefix = [[ 0 for i in range ( 26 )]
for i in range (N)]
preCalculate(s, prefix)
queries = [[ 1 , 4 ] , [ 3 , 4 ]]
q = len (queries)
for i in range (q):
print (performQueries(queries[i][ 0 ],
queries[i][ 1 ],
prefix))
|
C#
using System;
class GFG
{
static int N = 4 ;
static int performQueries( int l, int r, int [,] prefix)
{
l--;
r--;
bool flag = false ;
int count = 0;
for ( int i = 0; i < 26; i++)
{
int cnt = prefix[r, i];
if (l > 0)
cnt -= prefix[l - 1, i];
if (cnt % 2 == 1)
{
flag = true ;
count += cnt - 1;
}
else
count += cnt;
}
if (flag)
count += 1;
return count;
}
static void preCalculate( string s, int [,] prefix)
{
int n = s.Length;
for ( int i = 0; i < n; i++)
{
prefix[i, s[i] - 'a' ]++;
}
for ( int i = 1; i < n; i++)
{
for ( int j = 0; j < 26; j++)
prefix[i, j] += prefix[i - 1, j];
}
}
public static void Main()
{
string s = "amim" ;
int [,] prefix = new int [N, 26];
preCalculate(s, prefix);
int [,] queries = { { 1, 4 }, { 3, 4 } };
int q = queries.Length;
for ( int i = 0; i < q; i++)
{
Console.WriteLine( performQueries(queries[i, 0],
queries[i, 1], prefix) );
}
}
}
|
Javascript
<script>
let N = 4 ;
function performQueries(l, r, prefix)
{
l--;
r--;
let flag = false ;
let count = 0;
for (let i = 0; i < 26; i++)
{
let cnt = prefix[r][i];
if (l > 0)
cnt -= prefix[l - 1][i];
if (cnt % 2 == 1)
{
flag = true ;
count += cnt - 1;
}
else
count += cnt;
}
if (flag)
count += 1;
return count;
}
function preCalculate(s,prefix)
{
let n = s.length;
for (let i = 0; i < n; i++)
{
prefix[i][s[i].charCodeAt(0) - 'a' .charCodeAt(0)]++;
}
for (let i = 1; i < n; i++)
{
for (let j = 0; j < 26; j++)
prefix[i][j] += prefix[i - 1][j];
}
}
let s = "amim" ;
let prefix = new Array(N);
for (let i = 0; i < 26; i++)
{
prefix[i] = new Array(26);
for (let j = 0; j < 26; j++)
{
prefix[i][j] = 0;
}
}
preCalculate(s, prefix);
let queries = [[ 1, 4 ], [ 3, 4 ]];
let q = queries.length;
for (let i = 0; i < q; i++)
{
document.write( performQueries(queries[i][0],
queries[i][1], prefix) + "<br>" );
}
</script>
|
Time Complexity: O(26*N), as we are using nested loops to traverse 26*N times. Where N is the length of the string.
Auxiliary Space: O(26*N), as we are using extra space for the prefix matrix. Where N is the length of the string.
Share your thoughts in the comments
Please Login to comment...