📌  相关文章
📜  最长子字符串,其字符可以重新排列以形成回文

📅  最后修改于: 2021-04-24 21:04:49             🧑  作者: Mango

给定长度为N的字符串S ,其中仅包含小写字母。找到S的最长子字符串的长度,以便可以重新排列其中的字符以形成回文。

例子:

天真的方法:这个想法是生成所有可能的子字符串,并在其中保留每个字符的数量。初始化答案 值为0。如果每个字符的计数最多为一个奇数出现的偶数个字符,则可以重新排列子字符串以形成回文字符串。如果子字符串满足此属性,则更新答案。完成上述步骤后,打印最大长度。

时间复杂度: O(N 3 * 26)
辅助空间: O(N 2 * 26)

高效的方法:如果最多一个字符出现奇数次,则该字符串是回文字符串。因此,无需保留每个字符的总数。只知道它发生的次数是偶数或奇数就足够了。为此,请使用位掩码,因为小写字母的计数仅为26。

  1. 定义一个位掩码变量掩码,该掩码跟踪每个字符的出现是偶数还是奇数。
  2. 创建字典索引 跟踪每个位掩码的索引。
  3. 遍历给定的字符串S。首先,将字符从‘a’-‘z’转换为0-25并将此值存储在变量temp中。对于字符的每次出现,都要与掩码进行2 temp的按位XOR。
  4. 如果字符出现甚至 次数,它在掩码中的位将关闭,否则将打开。如果掩模是目前未在索引中,简单地分配本索引i给位掩码索引掩模
  5. 如果索引中包含遮罩 这意味着从index [mask]i ,所有字符的出现均是偶数,适用于回文子字符串。因此,如果此段从index [mask]i的长度大于答案,则更新答案。
  6. 要检查一个字符出现奇数次的子字符串,请在[0,25]上遍历变量j 。将x2 j的按位XOR存储在mask2中
  7. 如果mask2 存在于索引中,这是指该字符出现的奇数次和所有字符发生甚至若干在段索引[MASK2]次至i,这也是一个回文字符串的合适的条件。因此,如果该子字符串的长度大于答案,则用该子字符串的长度更新我们的答案
  8. 完成上述步骤后,打印子字符串的最大长度。

下面是上述方法的实现:

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)