给定长度为N的字符串S ,其中仅包含小写字母。找到S的最长子字符串的长度,以便可以重新排列其中的字符以形成回文。
例子:
Input: S = “aabe”
Output: 3
Explanation:
The substring “aab” can be rearranged to form “aba”, which is a palindromic substring.
Since the length of “aab” is 3 so output is 3.
Notice that “a”, “aa”, “b” and “e” can be arranged to form palindromic strings, but they are not longer than “aab”.
Input: S = “adbabd”
Output: 6
Explanation:
The whole string “adbabd” can be rearranged to form a palindromic substring. One possible arrangement is “abddba”.
Therefore, output length of the string i.e., 6.
天真的方法:这个想法是生成所有可能的子字符串,并在其中保留每个字符的数量。初始化答案 值为0。如果每个字符的计数最多为一个奇数出现的偶数个字符,则可以重新排列子字符串以形成回文字符串。如果子字符串满足此属性,则更新答案。完成上述步骤后,打印最大长度。
时间复杂度: O(N 3 * 26)
辅助空间: O(N 2 * 26)
高效的方法:如果最多一个字符出现奇数次,则该字符串是回文字符串。因此,无需保留每个字符的总数。只知道它发生的次数是偶数或奇数就足够了。为此,请使用位掩码,因为小写字母的计数仅为26。
- 定义一个位掩码变量掩码,该掩码跟踪每个字符的出现是偶数还是奇数。
- 创建字典索引 跟踪每个位掩码的索引。
- 遍历给定的字符串S。首先,将字符从‘a’-‘z’转换为0-25并将此值存储在变量temp中。对于字符的每次出现,都要与掩码进行2 temp的按位XOR。
- 如果字符出现甚至 次数,它在掩码中的位将关闭,否则将打开。如果掩模是目前未在索引中,简单地分配本索引i给位掩码索引掩模。
- 如果索引中包含遮罩 这意味着从index [mask]到i ,所有字符的出现均是偶数,这适用于回文子串。因此,如果此段从index [mask]到i的长度大于答案,则更新答案。
- 要检查一个字符出现奇数次的子字符串,请在[0,25]上遍历变量j 。将x与2 j的按位XOR存储在mask2中。
- 如果mask2 在索引中存在,这意味着该字符出现在奇数次,而所有字符在段index [mask2]到i的偶数次发生,这也是回文字符串的合适条件。因此,如果该子字符串的长度大于答案,则用该子字符串的长度更新我们的答案。
- 完成上述步骤后,打印子字符串的最大长度。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to get the length of longest
// substring whose characters can be
// arranged to form a palindromic string
int longestSubstring(string s, int n)
{
// To keep track of the last
// index of each xor
map index;
// Initialize answer with 0
int answer = 0;
int mask = 0;
index[mask] = -1;
// Now iterate through each character
// of the string
for(int i = 0; i < n; i++)
{
// Convert the character from
// [a, z] to [0, 25]
int temp = (int)s[i] - 97;
// Turn the temp-th bit on if
// character occurs odd number
// of times and turn off the temp-th
// bit off if the character occurs
// ever number of times
mask ^= (1 << temp);
// If a mask is present in the index
// Therefore a palindrome is
// found from index[mask] to i
if (index[mask])
{
answer = max(answer,
i - index[mask]);
}
// If x is not found then add its
// position in the index dict.
else
index[mask] = i;
// Check for the palindrome of
// odd length
for(int j = 0; j < 26; j++)
{
// We cancel the occurrence
// of a character if it occurs
// odd number times
int mask2 = mask ^ (1 << j);
if (index[mask2])
{
answer =max(answer,
i - index[mask2]);
}
}
}
return answer;
}
// Driver code
int main ()
{
// Given String
string s = "adbabd";
// Length of given string
int n = s.size();
// Function call
cout << (longestSubstring(s, n));
}
// This code is contributed by Stream_Cipher
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to get the length of longest
// substring whose characters can be
// arranged to form a palindromic string
static int longestSubstring(String s, int n)
{
// To keep track of the last
// index of each xor
Map index = new HashMap<>();
// Initialize answer with 0
int answer = 0;
int mask = 0;
index.put(mask, -1);
// Now iterate through each character
// of the string
for(int i = 0; i < n; i++)
{
// Convert the character from
// [a, z] to [0, 25]
int temp = (int)s.charAt(i) - 97;
// Turn the temp-th bit on if
// character occurs odd number
// of times and turn off the temp-th
// bit off if the character occurs
// ever number of times
mask ^= (1 << temp);
// If a mask is present in the index
// Therefore a palindrome is
// found from index[mask] to i
if (index.containsKey(mask))
{
answer = Math.max(answer,
i - index.get(mask));
}
// If x is not found then add its
// position in the index dict.
else
index.put(mask,i);
// Check for the palindrome of
// odd length
for (int j = 0;j < 26; j++)
{
// We cancel the occurrence
// of a character if it occurs
// odd number times
int mask2 = mask ^ (1 << j);
if (index.containsKey(mask2))
{
answer = Math.max(answer,
i - index.get(mask2));
}
}
}
return answer;
}
// Driver code
public static void main (String[] args)
{
// Given String
String s = "adbabd";
// Length of given string
int n = s.length();
// Function call
System.out.print(longestSubstring(s, n));
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the above approach
# Function to get the length of longest
# substring whose characters can be
# arranged to form a palindromic string
def longestSubstring(s: str, n: int):
# To keep track of the last
# index of each xor
index = dict()
# Initialize answer with 0
answer = 0
mask = 0
index[mask] = -1
# Now iterate through each character
# of the string
for i in range(n):
# Convert the character from
# [a, z] to [0, 25]
temp = ord(s[i]) - 97
# Turn the temp-th bit on if
# character occurs odd number
# of times and turn off the temp-th
# bit off if the character occurs
# ever number of times
mask ^= (1 << temp)
# If a mask is present in the index
# Therefore a palindrome is
# found from index[mask] to i
if mask in index.keys():
answer = max(answer,
i - index[mask])
# If x is not found then add its
# position in the index dict.
else:
index[mask] = i
# Check for the palindrome of
# odd length
for j in range(26):
# We cancel the occurrence
# of a character if it occurs
# odd number times
mask2 = mask ^ (1 << j)
if mask2 in index.keys():
answer = max(answer,
i - index[mask2])
return answer
# Driver Code
# Given String
s = "adbabd"
# Length of given string
n = len(s)
# Function call
print(longestSubstring(s, n))
C#
// C# program for the above approach
using System.Collections.Generic;
using System;
class GFG{
// Function to get the length of longest
// substring whose characters can be
// arranged to form a palindromic string
static int longestSubstring(string s, int n)
{
// To keep track of the last
// index of each xor
Dictionary index = new Dictionary();
// Initialize answer with 0
int answer = 0;
int mask = 0;
index[mask] = -1;
// Now iterate through each character
// of the string
for(int i = 0; i < n; i++)
{
// Convert the character from
// [a, z] to [0, 25]
int temp = (int)s[i] - 97;
// Turn the temp-th bit on if
// character occurs odd number
// of times and turn off the temp-th
// bit off if the character occurs
// ever number of times
mask ^= (1 << temp);
// If a mask is present in the index
// Therefore a palindrome is
// found from index[mask] to i
if (index.ContainsKey(mask) == true)
{
answer = Math.Max(answer,
i - index[mask]);
}
// If x is not found then add its
// position in the index dict.
else
index[mask] = i;
// Check for the palindrome of
// odd length
for(int j = 0; j < 26; j++)
{
// We cancel the occurrence
// of a character if it occurs
// odd number times
int mask2 = mask ^ (1 << j);
if (index.ContainsKey(mask2) == true)
{
answer = Math.Max(answer,
i - index[mask2]);
}
}
}
return answer;
}
// Driver code
public static void Main ()
{
// Given String
string s = "adbabd";
// Length of given string
int n = s.Length;
// Function call
Console.WriteLine(longestSubstring(s, n));
}
}
// This code is contributed by Stream_Cipher
6
时间复杂度: O(N * 26)
辅助空间: O(N * 26)