Maximum length palindrome that can be created with characters in range L and R

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 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 any odd frequency character.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define N 4
  
// Function to return the length of the
// longest palindrome that can be formed
// using the characters in the range [l, r]
int performQueries(int l, int r, int prefix[N][26])
{
  
    // 0-based indexing
    l--;
    r--;
  
    // Marks if there is an
    // odd frequency character
    bool flag = false;
  
    // Length of the longest palindrome
    // possible from characters in range
    int count = 0;
  
    // Traverse for all characters
    // and count their frequencies
    for (int i = 0; i < 26; i++) {
  
        // Find the frequency in range 1 - r
        int cnt = prefix[r][i];
  
        // Exclude the frequencies in range 1 - (l - 1)
        if (l > 0)
            cnt -= prefix[l - 1][i];
  
        // If frequency is odd, then add 1 less than
        // the original frequency to make it even
        if (cnt % 2 == 1) {
            flag = true;
            count += cnt - 1;
        }
        // Else completely add if even
        else
            count += cnt;
    }
  
    // If any odd frequency character
    // is present then add 1
    if (flag)
        count += 1;
  
    return count;
}
  
// Fucntion to pre-calculate the frequencies
// of the characters to reduce complexity
void preCalculate(string s, int prefix[N][26])
{
    int n = s.size();
  
    // Iterate and increase the count
    for (int i = 0; i < n; i++) {
        prefix[i][s[i] - 'a']++;
    }
  
    // Create a prefix type array
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < 26; j++)
            prefix[i][j] += prefix[i - 1][j];
    }
}
  
// Driver code
int main()
{
    string s = "amim";
  
    // Pre-calculate prefix array
    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]);
  
    // Perform queries
    for (int i = 0; i < q; i++) {
        cout << performQueries(queries[i][0],
                               queries[i][1], prefix)
             << endl;
    }
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach 
class GFG
{
      
static int N = 4 ;
  
// Function to return the length of the 
// longest palindrome that can be formed 
// using the characters in the range [l, r] 
static int performQueries(int l, int r, int prefix[][]) 
  
    // 0-based indexing 
    l--; 
    r--; 
  
    // Marks if there is an 
    // odd frequency character 
    boolean flag = false
  
    // Length of the longest palindrome 
    // possible from characters in range 
    int count = 0
  
    // Traverse for all characters 
    // and count their frequencies 
    for (int i = 0; i < 26; i++) 
    
  
        // Find the frequency in range 1 - r 
        int cnt = prefix[r][i]; 
  
        // Exclude the frequencies in range 1 - (l - 1) 
        if (l > 0
            cnt -= prefix[l - 1][i]; 
  
        // If frequency is odd, then add 1 less than 
        // the original frequency to make it even 
        if (cnt % 2 == 1)
        
            flag = true
            count += cnt - 1
        
          
        // Else completely add if even 
        else
            count += cnt; 
    
  
    // If any odd frequency character 
    // is present then add 1 
    if (flag) 
        count += 1
  
    return count; 
  
// Fucntion to pre-calculate the frequencies 
// of the characters to reduce complexity 
static void preCalculate(String s, int prefix[][]) 
    int n = s.length(); 
  
    // Iterate and increase the count 
    for (int i = 0; i < n; i++) 
    
        prefix[i][s.charAt(i) - 'a']++; 
    
  
    // Create a prefix type array 
    for (int i = 1; i < n; i++) 
    
        for (int j = 0; j < 26; j++) 
            prefix[i][j] += prefix[i - 1][j]; 
    
  
// Driver code 
public static void main(String args[])
    String s = "amim"
  
    // Pre-calculate prefix array 
    int prefix[][] = new int[N][26]; 
    preCalculate(s, prefix); 
  
    int queries[][] = { { 1, 4 }, { 3, 4 } }; 
    int q = queries.length; 
  
    // Perform queries 
    for (int i = 0; i < q; i++)
    
        System.out.println( performQueries(queries[i][0], 
                            queries[i][1], prefix) ); 
    
}
}
  
// This code is contributed by Arnab Kundu

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
N = 4
  
# Function to return the length of the
# longest palindrome that can be formed
# using the characters in the range [l, r]
def performQueries(l, r, prefix):
  
    # 0-based indexing
    l -= 1
    r -= 1
  
    # Marks if there is an
    # odd frequency character
    flag = False
  
    # Length of the longest palindrome
    # possible from characters in range
    count = 0
  
    # Traverse for all characters
    # and count their frequencies
    for i in range(26):
  
        # Find the frequency in range 1 - r
        cnt = prefix[r][i]
  
        # Exclude the frequencies in range 1 - (l - 1)
        if (l > 0):
            cnt -= prefix[l - 1][i]
  
        # If frequency is odd, then add 1 less than
        # the original frequency to make it even
        if (cnt % 2 == 1):
            flag = True
            count += cnt - 1
          
        # Else completely add if even
        else:
            count += cnt
      
    # If any odd frequency character
    # is present then add 1
    if (flag):
        count += 1
  
    return count
  
# Fucntion to pre-calculate the frequencies
# of the characters to reduce complexity
def preCalculate(s, prefix):
  
    n = len(s)
  
    # Iterate and increase the count
    for i in range(n): 
        prefix[i][ord(s[i]) - ord('a')] += 1
      
  
    # Create a prefix type array
    for i in range(1, n): 
        for j in range(26):
            prefix[i][j] += prefix[i - 1][j]
      
# Driver code
s = "amim"
  
# Pre-calculate prefix array
prefix = [[0 for i in range(26)] 
             for i in range(N)]
  
preCalculate(s, prefix)
  
queries = [[1, 4] , [3, 4]] 
q = len(queries)
  
# Perform queries
for i in range(q): 
    print(performQueries(queries[i][0],
                         queries[i][1], 
                         prefix))
      
# This code is contributed 
# by mohit kumar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach 
using System;
  
class GFG
{
      
static int N = 4 ;
  
// Function to return the length of the 
// longest palindrome that can be formed 
// using the characters in the range [l, r] 
static int performQueries(int l, int r, int[,] prefix) 
  
    // 0-based indexing 
    l--; 
    r--; 
  
    // Marks if there is an 
    // odd frequency character 
    bool flag = false
  
    // Length of the longest palindrome 
    // possible from characters in range 
    int count = 0; 
  
    // Traverse for all characters 
    // and count their frequencies 
    for (int i = 0; i < 26; i++) 
    
  
        // Find the frequency in range 1 - r 
        int cnt = prefix[r, i]; 
  
        // Exclude the frequencies in range 1 - (l - 1) 
        if (l > 0) 
            cnt -= prefix[l - 1, i]; 
  
        // If frequency is odd, then add 1 less than 
        // the original frequency to make it even 
        if (cnt % 2 == 1)
        
            flag = true
            count += cnt - 1; 
        
          
        // Else completely add if even 
        else
            count += cnt; 
    
  
    // If any odd frequency character 
    // is present then add 1 
    if (flag) 
        count += 1; 
  
    return count; 
  
// Fucntion to pre-calculate the frequencies 
// of the characters to reduce complexity 
static void preCalculate(string s, int[,] prefix) 
    int n = s.Length; 
  
    // Iterate and increase the count 
    for (int i = 0; i < n; i++) 
    
        prefix[i, s[i] - 'a']++; 
    
  
    // Create a prefix type array 
    for (int i = 1; i < n; i++) 
    
        for (int j = 0; j < 26; j++) 
            prefix[i, j] += prefix[i - 1, j]; 
    
  
// Driver code 
public static void Main()
    string s = "amim"
  
    // Pre-calculate prefix array 
    int[,] prefix = new int[N, 26]; 
    preCalculate(s, prefix); 
  
    int[,] queries = { { 1, 4 }, { 3, 4 } }; 
    int q = queries.Length; 
  
    // Perform queries 
    for (int i = 0; i < q; i++)
    
        Console.WriteLine( performQueries(queries[i, 0], 
                            queries[i, 1], prefix) ); 
    
}
}
  
// This code is contributed by Code_Mech

chevron_right


Output:

3
1


My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.