Longest Palindrome
类似消消乐,把string里面的值逐个读入一个hashmap。 如果已经有了,就把value值减一,最大长度加二。value值只会在0,1之间变动。最后,看一下是否有value值为1的key存在,只要存在,不管有几个,只需要把最大长度+1。
hashMap; value 0/1; if val = 1, length + 1;
hashMap.put(key, hashMap.get(key) - 1); //既放入新的已配对字母,又把已经在hashMap里面的value改为0
String key = String.valueOf(s.charAt(i)); //从字符串中取得单个字母
for (Integer value : hashMap.values()) { if (value != 0) { return max_length + 1; } } //不用break 直接return
字符串匹配算法总结
KMP
KMP的next 数组相当于告诉我们:当模式串中的某个字符跟文本串中的某个字符匹配失配时,模式串下一步应该跳到哪个位置。如模式串中在j 处的字符跟文本串在i 处的字符匹配失配时,下一步用next [j] 处的字符继续跟文本串i 处的字符匹配,相当于模式串向右移动 j - next[j] 位。
next 数组的求解就是找最大对称长度的前缀后缀,然后整体右移一位,初值赋为-1
"前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。
Rabin-Karp
- 假设子串的长度为M,目标字符串的长度为N
- 计算子串的hash值
- 计算目标字符串中每个长度为M的子串的hash值(共需要计算N-M+1次)
- 比较hash值
- 如果hash值不同,字符串必然不匹配,如果hash值相同,还需要使用朴素算法再次判断
朴素匹配
对主串的每一个字符作为子串开头,与要匹配的字符串进行匹配。此过程中,对主串做大循环,每个字符开头做T的长度的小循环,直到匹配成功或全部遍历完成为止。
两字母相等时,在小循环内继续循环比较。
两字母不等时,则回退。对于i,回退的位置是i = i - j +2。对于j,回退到1,重新从开始比较待匹配串。
Valid Palindrome
使用两根指针遍历整个字符串即可.
假定有指针i, j, 其中i是从前往后遍历, j是从后往前遍历.
当i在j左边时继续循环, 每一次将i右移到数字/字母上, j左移到数字/字母上,
比较二者对应的字符串内的字符是否相同, 不相同则原字符串不是回文串.
如果全部的比较都相同, 说明是回文串.
题目是“不区分大小写”时,用Character.toLowerCase(s.charAt(left)
Longest Palindromic Substring
这道题一共有五种解法:
Manacher's Algorithm - O(n) -----可以背诵
后缀数组 Suffix Array - O(nlogn)
动态规划 Dynamic Programming - O(n^2)
枚举法 Enumeration - O(n^2) ------推荐
暴力解法 Brute-force - O(n^3)
有关Manacher's Algorithm的方法可以参考这个链接:最长回文子串——Manacher 算法
基于中心点枚举的方法: 时间复杂度O(n^2)
方法:由于回文子串的对称性,且整个字符串中的所有字符,以及字符间的空隙,都可能是某个回文子串的对称轴位置。可以遍历这些位置,在每个位置上同时向左和向右扩展,直到左右两边的字符不同,或者达到边界。且分为两种情况,一个是从一点为中心向两边扩展,一个是以两点的中间间隔为中心,向两边扩展。