给定一个长度为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进行按位异或。
- 如果字符出现偶 多次,它在掩码中的位将关闭,否则它将打开。如果掩模是目前未在索引中,简单地分配本索引i给位掩码索引掩模。
- 如果掩码存在于索引中 这意味着从index[mask]到i ,所有字符的出现都是偶数,这适用于回文子串。因此,如果该段从index[mask]到i 的长度大于答案,则更新答案。
- 要检查一个字符出现奇数次的子字符串,请在[0, 25] 上迭代变量j 。将x与2 j 的按位异或存储在mask2 中。
- 如果掩码2 存在于索引中,这意味着该字符出现奇数次,并且所有字符在段index[mask2]到i 中出现偶数次,这也是回文字符串的合适条件。因此,如果该子串的长度大于 answer ,则用该子串的长度更新我们的答案。
- 完成上述步骤后打印子串的最大长度。
下面是上述方法的实现:
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
Javascript
6
时间复杂度: O(N * 26)
辅助空间: O(N * 26)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。