📌  相关文章
📜  可以通过交换字符而成为回文的最长子字符串

📅  最后修改于: 2021-04-27 23:27:39             🧑  作者: Mango

给定一个数字字符串S ,任务是找到可以做成回文的最长的非空子字符串。

例子:

天真的方法:解决此问题的最简单方法是生成所有可能的子字符串,并通过对每个子字符串中的字符进行计数来检查每个子字符串是否可以成为回文,并检查是否仅存在一个或没有奇数个频繁字符或不是。

时间复杂度: O(N 3 )
辅助空间: O(1)

高效方法:为了优化上述方法,解决此问题的想法是使用位屏蔽和动态编程。如果每个包含的数字(可能是一个除外)的数量为偶数,则可以形成回文集。请按照以下步骤解决问题:

  • 初始化一个整数变量,例如mask 。如果对应数字的计数为偶数,则掩码中的一位为0,如果为奇数则为1。
  • 遍历字符串,并在遍历字符串,在变量mask中跟踪奇数/偶数计数
  • 如果再次遇到相同的掩码,则具有相同掩码第一个位置(不包括)与当前位置(不包括)之间的子数组将具有所有带有偶数的数字。
  • 让子字符串的大小存储在变量中,例如res
  • 初始化一个数组,例如dp [] ,以跟踪大小为1024的每个掩码的最小(第一个)位置,因为输入仅包含10个数字(“ 0123456789”),并且位只能有2 ^ 10或1024个变化面具。
  • 子字符串的大小可以通过从当前位置减去它来计算。请注意,零掩码的位置是-1,因为要包含第一个字符。
  • 此外,检查是从目前逐个位不同的所有口罩。换句话说,如果两个掩码的位数相差一位,则意味着子字符串中存在一个奇数
  • res打印为此类子字符串中最长的长度。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the Longest
// substring that can be made a
// palindrome by swapping of characters
int longestSubstring(string s)
{
   
    // Initialize dp array of size 1024
    int dp[1024];
 
    // Initializeing dp array with length of s
    fill(dp, dp + 1024, s.size());
 
    // Initializing mask and res
    int res = 0, mask = 0;
    dp[0] = -1;
 
    // Traverse the string
    for (int i = 0; i < s.size(); ++i)
    {
 
        // Find the mask of the current character
        mask ^= 1 << (s[i] - 48);
 
        // Finding the length of the longest
        // substring in s which is a
        // palindrome for even count
        res = max(res, i - dp[mask]);
 
        // Finding the length of the longest
        // substring in s which is a
        // palindrome for one odd count
        for (int j = 0; j <= 9; ++j)
 
            // Finding maximum length of
            // substring having one odd count
            res = max(res, i - dp[mask ^ (1 << j)]);
 
        // dp[mask] is minimum of
        // current i and dp[mask]
        dp[mask] = min(dp[mask], i);
    }
 
    // Return longest length of the substring
    // which forms a palindrome with swaps
    return res;
}
 
// Driver Code
int main()
{
   
    // Input String
    string s = "3242415";
 
    // Function Call
    cout << longestSubstring(s);
    return 0;
}
 
// This code is contributed by subhammahato348.


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to find the Longest
    // substring that can be made a
    // palindrome by swapping of characters
    public static int longestSubstring(String s)
    {
        // Initialize dp array of size 1024
        int dp[] = new int[1024];
 
        // Initializeing dp array with length of s
        Arrays.fill(dp, s.length());
 
        // Initializing mask and res
        int res = 0, mask = 0;
        dp[0] = -1;
 
        // Traverse the string
        for (int i = 0; i < s.length(); ++i) {
 
            // Find the mask of the current character
            mask ^= 1 << (s.charAt(i) - '0');
 
            // Finding the length of the longest
            // substring in s which is a
            // palindrome for even count
            res = Math.max(res, i - dp[mask]);
 
            // Finding the length of the longest
            // substring in s which is a
            // palindrome for one odd count
            for (int j = 0; j <= 9; ++j)
 
                // Finding maximum length of
                // substring having one odd count
                res = Math.max(res,
                               i - dp[mask ^ (1 << j)]);
 
            // dp[mask] is minimum of
            // current i and dp[mask]
            dp[mask] = Math.min(dp[mask], i);
        }
 
        // Return longest length of the substring
        // which forms a palindrome with swaps
        return res;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Input String
        String s = "3242415";
 
        // Function Call
        System.out.println(longestSubstring(s));
    }
}


Python3
# Python3 program for the above approach
 
# Function to find the Longest
# substring that can be made a
# palindrome by swapping of characters
def longestSubstring(s):
     
    # Initialize dp array of size 1024
    dp = [1024 for i in range(1024)]
 
    # Initializeing dp array with length of s
    # Arrays.fill(dp, s.length());
 
    # Initializing mask and res
    res, mask = 0, 0
    dp[0] = -1
 
    # Traverse the string
    for i in range(len(s)):
         
        # Find the mask of the current character
        mask ^= 1 << (ord(s[i]) - ord('0'))
 
        # Finding the length of the longest
        # substring in s which is a
        # palindrome for even count
        res = max(res, i - dp[mask])
 
        # Finding the length of the longest
        # substring in s which is a
        # palindrome for one odd count
        for j in range(10):
             
            # Finding maximum length of
            # substring having one odd count
            res = max(res, i - dp[mask ^ (1 << j)])
 
        # dp[mask] is minimum of
        # current i and dp[mask]
        dp[mask] = min(dp[mask], i)
 
    # Return longest length of the substring
    # which forms a palindrome with swaps
    return res
 
# Driver Code
if __name__ == '__main__':
     
    # Input String
    s = "3242415"
 
    # Function Call
    print(longestSubstring(s))
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
class GFG
{
 
  // Function to find the Longest
  // substring that can be made a
  // palindrome by swapping of characters
  public static int longestSubstring(string s)
  {
    // Initialize dp array of size 1024
    int []dp = new int[1024];
 
    // Initializeing dp array with length of s
    for (int i = 0; i < 1024; ++i)
    {
      dp[i] = s.Length;
    }
 
    // Initializing mask and res
    int res = 0, mask = 0;
    dp[0] = -1;
 
    // Traverse the string
    for (int i = 0; i < s.Length; i++)
    {
 
      // Find the mask of the current character
      mask = mask ^ (1 << (s[i] - '0'));
 
      // Finding the length of the longest
      // substring in s which is a
      // palindrome for even count
      res = Math.Max(res, i - dp[mask]);
 
      // Finding the length of the longest
      // substring in s which is a
      // palindrome for one odd count
      for (int j = 0; j < 10; j++)
      {
 
        // Finding maximum length of
        // substring having one odd count
        res = Math.Max(res,i - dp[mask ^ (1 << j)]);
      }
 
      // dp[mask] is minimum of
      // current i and dp[mask]
      dp[mask] = Math.Min(dp[mask], i);
    }
 
    // Return longest length of the substring
    // which forms a palindrome with swaps
    return res;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
 
    // Input String
    string s = "3242415";
 
    // Function Call
    Console.WriteLine(longestSubstring(s));
  }
}
 
// This code is contributed by AnkThon


输出:
5

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