写一个函数:def,对于给定一个由N个小写英文字母组成的字符串S,返回每个字母出现偶数次的最长子字符串的长度。子字符串被定义为字符串的连续段。如果不存在这样的子字符串,返回0。
关键考点:动态哈希+状态压缩
例子:1. 给定S =“bdaaadadb”,函数应该返回6。每个字母出现偶数次的子字符串是"aa", “adad”, “daaada"和"aaadad”。其中最长的是6。
2. 给定S = “abacb”,函数应该返回0。不存在每个字母出现偶数次的非空子字符串。3.给定S = 'zthtzh ',函数应该返回6。整个字符串中的每个字母出现的次数都是偶数。对以下假设写一个有效的算法,注:N为范围[1…100,000]内的整数,字符串S只包含小写字母(‘a’-'z)。
类似于网易的笔试第二题:【秋招笔试复盘】秋招的第一场笔试——网易。
def solution(s):
state = 0
statemap = {}
statemap[0] = -1
ans = 0
for i in range(len(s)):
ind = ord(s[i]) - ord('a')
stack ^= (1 << ind)
if state in statemap:
ans = max(ans, i-statemap[state])
else:
statemap[state] = i
return ans
定义字符串中每个字母出现的次数是偶数为好串,问对于一个字符串,有多少子序列是好串(子序列可以不连续)?
"ababa"有"aa"4个,"bb"1个,"abab"1个,"abba"1个,"baba"1个
统计字符串中的各字母数,然后排列组合算所有可能数。例如a有5个,那么可以选择4个a,2个啊,0个a,对应是C54+C52+C50的总可能数,其他字母也一样,然后相乘就行。
特别注意他和前面一题连续子串的区别,因为本题子串可以不连续,因此不能用前缀思想计算。硬做dp状态2^26太多了。实际上细想一下,不连续子串本质上就是排列组合问题。
from collections import Counter
from functools import reduce
import math
MOD = 10**9+7
strings = input()
scount = Counter(strings)
cntlist = [v for k, v in scount.items()]
computelist = []
for cnt in cntlist:
p = cnt
if cnt % 2:
p -= 1
comp = 0
for i in range(p, -1, -2):
comp += math.comb(cnt, i) ## compute C cnt i
computelist.append(comp)
ans = (reduce((lambda x, y: x*y), computelist) - 1) % MOD
print(ans)