给定一个数字字符串S ,任务是找到可以做成回文的最长的非空子字符串。
例子:
Input: S = “3242415”
Output: 5
Explanation: “24241” is the longest such substring which can be converted to the palindromic string “24142”.
Input: S = “213123”
Output: 6
Explanation: “213123” such substring which can be converted to the palindromic string “231132”.
天真的方法:解决此问题的最简单方法是生成所有可能的子字符串,并通过对每个子字符串中的字符进行计数来检查每个子字符串是否可以成为回文,并检查是否仅存在一个或没有奇数个频繁字符或不是。
时间复杂度: 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
Javascript
输出:
5
时间复杂度: O(10 * N)
辅助空间: O(1024)