可以用 L 和 R 范围内的字符创建的最大长度回文
给定一个字符串str和Q查询。每个查询由两个数字L和R组成。任务是找到可以用[L, R]范围内的字符创建的最大长度回文。
例子:
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
方法:设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