1542. 找出最长的超赞子字符串
大约 4 分钟
---
1542. 找出最长的超赞子字符串
- 标签:位运算、哈希表、字符串
- 难度:困难
题目链接
题目大意
描述:给定一个由数字组成的字符串 。
要求:返回 中最长的"超赞子字符串"的长度。超赞子字符串是指一个字符串,可以重新排列为回文字符串。
说明:
- 。
- 只包含数字字符 。
示例:
- 示例 1:
输入:s = "3242415"
输出:5
解释:"24241" 是最长的超赞子字符串,交换其中的字符后,可以得到回文 "24142"- 示例 2:
输入:s = "12345678"
输出:1解题思路
思路 1:位运算 + 哈希表
1. 核心思想
一个字符串能重排成回文串的充要条件:最多只有一个字符出现奇数次。
在子字符串中,字符出现的奇偶性是关键信息。我们可以用一个 位的二进制掩码表示前缀 中各数字的奇偶性(第 位为 表示数字 出现奇数次)。
设 为前缀 的奇偶性掩码,则子串 的奇偶性掩码为 。
子串可以重排为回文串 其奇偶性掩码中 的个数 。
问题转化为:找到最长的子串 ,使得 中 的个数 。等价于 为 或 的幂。
2. 具体步骤
第 1 步:初始化哈希表 ,记录每个掩码第一次出现的位置(索引 , 从 到 ,其中 )。
第 2 步:遍历 ,更新 。
第 3 步:对于当前 :
- 如果 之前出现过,则子串长度 = (该子串中所有字符出现偶数次,可以排成回文)。
- 对于每个 ,检查 是否出现过。若出现过,则子串中有一个字符出现奇数次(即 ),其余为偶数次,长度 = 。
- 更新最大值。
第 4 步:如果 不在哈希表中,记录当前位置。
3. 举例说明
以 为例:
遍历过程:
i char mask(二进制) 考察
0 '3' 0000001000 首次出现
1 '2' 0000001100 首次出现
2 '4' 0000010100 首次出现
3 '2' 0000011000 mask 首次出现在 i=0?不匹配。检查掩码差一位:
0000011000 ^ 0000010000 = 0000001000(8) 出现在 i=0 → 长度 3
4 '4' 0000001000 mask 出现在 i=0 → 长度 4
5 '1' 0000001010 首次出现
6 '5' 0000011010 检查 0000011010 ^ 0000001010 = 0000010000(16) 出现在...等等
实际要检查所有一位差异最终最长超赞子串长度为 。
4. 关键优化
- 掩码只有 种可能,哈希表最多存储 个键。
- 每次检查 种一位差异,总复杂度 。
思路 1:代码
class Solution:
def longestAwesome(self, s: str) -> int:
# 记录每个掩码第一次出现的位置
first_pos = {0: -1} # 前缀为空时 mask=0,位置为 -1
mask = 0
ans = 0
for i, ch in enumerate(s):
d = int(ch)
mask ^= (1 << d) # 翻转第 d 位的奇偶性
# 情况 1:所有字符出现偶数次
if mask in first_pos:
ans = max(ans, i - first_pos[mask])
else:
first_pos[mask] = i
# 情况 2:一个字符出现奇数次,其余偶数次
for j in range(10):
target = mask ^ (1 << j)
if target in first_pos:
ans = max(ans, i - first_pos[target])
return ans思路 1:复杂度分析
- 时间复杂度:。
- 空间复杂度:,掩码数不超过 。
思路 2:数组代替哈希表
由于掩码范围是 ,可以用数组代替哈希表以获得更快的速度。
class Solution:
def longestAwesome(self, s: str) -> int:
first_pos = [-1] * 1024
first_pos[0] = -1
mask = 0
ans = 0
for i, ch in enumerate(s):
mask ^= (1 << (ord(ch) - ord('0')))
if first_pos[mask] != -1:
ans = max(ans, i - first_pos[mask])
else:
first_pos[mask] = i
for j in range(10):
target = mask ^ (1 << j)
if first_pos[target] != -1:
ans = max(ans, i - first_pos[target])
return ans思路 2:复杂度分析
- 时间复杂度:。
- 空间复杂度:。