📜  可以用 L 和 R 范围内的字符创建的最大长度回文

📅  最后修改于: 2022-05-13 01:57:07.527000             🧑  作者: Mango

可以用 L 和 R 范围内的字符创建的最大长度回文

给定一个字符串strQ查询。每个查询由两个数字LR组成。任务是找到可以用[L, R]范围内的字符创建的最大长度回文。
例子:

方法:prefix[i][j]是一个数组,表示字符char(j+97)在1到i范围内的频率。对于从 L 到 R 的任何范围,计算偶数频率和奇数频率。由于odd-1 是偶数,它也可以对回文字符串有所贡献。奇频字符也要留个记号,可以插在中间。因此,可能的最长回文长度将是所有偶数和奇数 1 频率之和,如果存在任何奇数频率字符,则加 1。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
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;
}
 
// Function 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;
}


Java
// 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;
}
 
// Function 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


Python3
# 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
 
# Function 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


C#
// 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;
}
 
// Function 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


Javascript


输出:
3
1