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

📅  最后修改于: 2021-09-07 05:15:15             🧑  作者: 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进行按位异或。
  4. 如果字符出现 多次,它在掩码中的位将关闭,否则它将打开。如果掩模是目前未在索引中,简单地分配本索引i给位掩码索引掩模
  5. 如果掩码存在于索引中 这意味着从index[mask]i ,所有字符的出现都是偶数,这适用于回文子串。因此,如果该段从index[mask]i 的长度大于答案,则更新答案。
  6. 要检查一个字符出现奇数次的子字符串,请在[0, 25] 上迭代变量j 。将x2 j 的按位异或存储在mask2 中
  7. 如果掩码2 存在于索引中,这意味着该字符出现了奇数次并且所有字符在段index[mask2]i 中出现了偶数次,这也是回文字符串的合适条件。因此,如果该子串的长度大于 answer ,则用该子串的长度更新我们的答案
  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


Javascript


输出:
6

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live