← 博客

string

题单

KMP

https://www.zhihu.com/question/21923021/answer/37475572

28. 找出字符串中第一个匹配项的下标

模式串:abababzababab

第一步:一边遍历模式串,一边构造next数组。

  • next[i]表示字符串s[0:i+1]的前缀和后缀最大的公共长度
  • 初始化j=0,i从1遍历到n-1。j的位置表示,此时s[:j]是公共前后缀
  • 遍历时,如果此时有公共前后缀,不断比较s[i]和s[j],一旦发现他们不同,则在循环中回退j,直到s[:j]成为公共前后缀。回退到此时的次长公共前后缀,将j移动到next[j-1]即可
  • 再次比较s[i]和s[j],如果相同,则移动j,并且为next[i]赋值

第二步:比较两个字符串
abeababeabf
abeabf

  • i遍历字符串,j指向模式串。一次循环中,j的位置表示needle[0:j]和字符串匹配
  • 当此时有匹配,检查haystack[i]与needle[j]是否相同,如果不相同,回退j至next[j-1]
  • 再次比较haystack[i]与needle[j],如果相同,移动j

最小表示法

1163. 按字典序排在最后的子串

i表示当前找到的最优起始位置
j表示候选最优起始位置
k表示比较的偏移

  • s[i+k]==s[j+k], k+=1
  • s[i+k]<s[j+k],此时可以更新j为最大起始位置,并且下一个候选者为max(j+1, i+k+1). 考虑字符串cacacb,i=0,j=2.
    j+=1 肯定是没问题的,但是效率不高。s[i+k]<s[j+k],所以s[i+k]肯定不能是最优起始位置。
  • s[i+k]>s[j+k],j挑战失败,需要往后移动。说明之前比较的都相等,s[i]==s[j], …, s[i+k-1]==s[j+k-1],而且s[i:i+k+1]肯定是降序的,不然i早就被替代了。写出一个例子dcbdcba,j=j+k+1

其它

767. 重构字符串

按频数从大到小排序,然后先填满偶数位,再填满奇数位

271. 字符串的编码与解码

分块编码。

dummy_input = [“Hello”,“World”]

用前四位表示这一块的长度,然后加上这一块的实际内容

解码时,用 index追踪解码到哪里了,注意循环条件为while index<len(s)-3:

因为要确保当前循环包含了长度信息。

  • 优化 1:变长编码,Hello 被编码为 5:Hello
  • 优化 2:二进制编码。用base64 包。