algorithm - 每个字符出现偶数次(可能为零)的最长子串

标签 algorithm computer-science

Suppose we have a string s. We want to find the length of the longest substring of s such that every character in the substring appears even number of times (possible zero).
WC Time: O(nlgn). WC space: O(n)

首先,很明显子字符串必须是偶数长度。其次,我熟悉滑动窗口方法,我们在其中锚定一些 right 索引并寻找最左边的索引来匹配您的标准。我试图在这里应用这个想法,但无法真正表达它。

此外,在我看来,优先级队列可能会派上用场(因为 O(nlgn) 要求有点暗示)

我很乐意提供帮助!

最佳答案

让我们定义以下位集:

B[c,i] = 1 if character c appeared in s[0,...,i] even number of times.

计算 B[c,i] 需要线性时间(对于所有值):

for all c:
  B[c,-1] = 0
for i from 0 to len(arr):
  B[c, i] = B[s[i], i-1] XOR 1

由于字母表的大小不变,位集也是如此(对于每个 i)。

注意条件:

every character in the substring appears even number of times

对于子字符串 s[i,j] 为真当且仅当索引 i 的位集与索引 j 的位集相同时> (否则,该子串中有重复奇数次的位;反之:如果有重复次数的位,则其位不能相同)。

因此,如果我们将所有位集存储在某个集合(哈希集/树集)中,并且只保留最新条目,则此预处理需要 O(n)O(nlogn) 时间(取决于散列/树集)。

在第二次迭代中,对于每个索引,找到具有相同位集的较远索引(O(1)/O(logn),取决于哈希/树集),找到子字符串长度,并将其标记为候选。最后,选择最长的候选人。

此解决方案的位集空间为 O(n),时间为 O(n)/O(nlogn),具体取决于是否使用哈希/树解决方案。


伪代码:

def NextBitset(B, c): # O(1) time
  for each x in alphabet \ {c}:
    B[x, i] = B[x, i-1]
   B[c, i] = B[c, i-1] XOR 1

for each c in alphabet: # O(1) time
  B[c,-1] = 0
map = new hash/tree map (bitset->int)

# first pass: # O(n)/O(nlogn) time
for i from 0 to len(s):
   # Note, we override with the latest element.
   B = NextBitset(B, s[i])
   map[B] = i

for each c in alphabet: # O(1) time
  B[c,-1] = 0
max_distance = 0
# second pass: O(n)/ O(nlogn) time.
for i from 0 to len(s):
  B = NextBitset(B, s[i])
  j = map.find(B)  # O(1) / O(logn)
  max_distance = max(max_distance, j-i)

关于algorithm - 每个字符出现偶数次(可能为零)的最长子串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50564676/

相关文章:

c - 确定每个元素在数组中出现的频率?

java - 反转 32 位无符号整数的位

algorithm - 大 O 归纳法证明

c - 定义与变量的存在

algorithm - 获取所有可能路径的有效方法+特殊细节

c# - 动态创建路线图

c# - 比较两个列表并找到这两个列表之间的增量的最有效模式/算法是什么?

algorithm - 你如何证明一个序列的大θ是它的首项?

algorithm - 大 Ө 符号到底代表什么?

algorithm - 在 Python 中计算一个巨大的斐波那契数模 m