算法
大数据
- bitmap
排序
-
桶排序
-
计数排序
-
字典序
字符串
-
字符串匹配
- KMP
- 关键是构造出一个数组, 通过该数据判断从哪一个字符开始匹配
- KMP
-
字符串最长的不重复字串
- 滑动窗口算法, 根据 start 与 end 两个变量锁定一个窗口; 为了进一步提高字符串不重复的查找效率, 采用dict存储, 字符为key, 下标为value, 会实时的更新
- 关于采用dict的
- 在更新index时, 需要将新的index与老的index进行比较, 老的大, 则表示出现了重复的字符, 则在更新index时, 将老的index + 1, 该值就是下一个字串的start, 一次类推
- 关于采用dict的
- 滑动窗口算法, 根据 start 与 end 两个变量锁定一个窗口; 为了进一步提高字符串不重复的查找效率, 采用dict存储, 字符为key, 下标为value, 会实时的更新
-
字符串的最长回文
- 中心扩展法O(n^2), 需要注意字符串长度的奇偶性
- manacher算法O(n)
-
-
添加"#"符号
-
最重要的是要明白 max_right 与 center 与 i 与 pp[i']的关系, max_right - i > P[i']则P[i'] == P[i], 否则只是部分匹配, 其中 i' 的为 2 * center - i
-
用到的技巧: 添加'#'将原来的字符串都转为奇数长度
-
manacher最终的目的就是计算P[i]数组, 使用mancher就是求出P[i]
-
核心代码
for(int i = 0; i < adapted_s.size(); i++){ // 其中max_right与center锁定的字符串就是一个回文, 当max_right大于i时, 是该回文字符串的字串 // 其中的max_left是由center与max_right, 动态的改变max_right和center完成max_left的改变 p[i] = max_right > i ? (p[2 * center - i] >l max_right - i+1 ? max_right - i+1 : p[2 * center - i]) : 1; while(i - p[i] >= 0 && s2[p[i] + i] == s2[i - p[i]]) // 这里继续完善p[i] p[i]++; if(p[i] + i - 1 > max_right){ // 定位max_right mx = p[i] + i - 1; mid = i; } .... }
-
-
完整代码:
```
class Solution:def longestPalindrome(self, s): """ :type s: str :rtype: str """ new_s = '#' + '#'.join(s) + '#' new_s_len = len(new_s) p = [0] * new_s_len max_right = 0 center = 0 for i in range(new_s_len): if i < max_right: p[i] = min(p[2 * center - i], max_right - 1) else: p[i] = 1 while i - p[i] >= 0 and i + p[i] < new_s_len and new_s[p[i] + i] == new_s[i - p[i]]: p[i] += 1 if p[i] + i - 1 > max_right: max_right = p[i] + i - 1 center = i max_value = max(p) max_index = p.index(max_value) sub = new_s[max_index - max_value + 1:max_index + max_value] return sub.replace('#', '')
-
- 还可以将中心扩展与manacher的'#'思想结合