Longest Palindromic Substring解题心得

来源:互联网 发布:java 积分兑换商城 编辑:程序博客网 时间:2024/06/08 02:39

Longest Palindromic Substring解题心得

原题描述:https://leetcode.com/problems/longest-palindromic-substring/description/

  • Longest Palindromic Substring解题心得
    • 第一种思路
      • 以每个字母为中心向两端进行匹配
      • 复杂度分析
    • 第二种思路
      • 利用回文的性质减少重复性搜索
      • 复杂度分析

第一种思路

以每个字母为中心向两端进行匹配

对于最长回文子串问题,我想到的第一种解题思路就是顺序遍历字符串s,以回文子串的中心为目标匹配搜索回文子串

设置中心下标i,设定left,right哨兵,以当前s[i]为中心进行向两端的字母匹配,同时每次比较并记录最大回文子串半径maxR(即子串长度的一半),以及子串的左右位置left,right

  • 坑点:仔细思考下,这样的思路缺少了对偶数长度回文子串的搜索,所以可以进行如下改进
    1. 使i遍历s.size()*2次,每当i遍历到偶数则,以s[i/2]为中心进行回文匹配;当i为奇数时,则设定left=i/2,right=(i+1)/2,从而双向扩张搜索匹配的回文
    2. 为s间隔插入特殊字符,如插入’$‘ 或者‘ ’,匹配得到的最大半径不是实际最长回文子串的半径,而是中间含有特殊字符的字符串,需要另外过滤得到真实值
      这里写图片描述
      这里写图片描述

复杂度分析

  • 时间复杂度
    • 纠正后的算法,设定k为最长子串的半径,n为字符串长度,则时间复杂度为O(nk),最差情况下为O(n2)
  • 空间复杂度
    • 由于算法只是对字符串进行遍历,对于第一种纠正方法,需要n的空间,第二种则需要2n的空间,于是我们可以得出空间复杂度为O(n)

第二种思路

利用回文的性质减少重复性搜索

分析发现回文拥有一种特质,即左右的对称性

所以我们以第一种算法的思路为基础进行改良,当我们以i为中心向两边搜索时,已知左边的字母的回文半径,在左边位置left下,回文半径为R[left],

右边字母由于对称性可以知道,只要以left为中心的回文在以flag为中心的回文范围内,即left-(flag-R[flag])>R[left] 或者 (flag+R[flag])-right>R[right]则可以断定R[right]=R[left](注:具体实现需要根据R[flag]的定义形式,判断临界值情况)
这里写图片描述

if (R[j]>=right-i){    flag=i;    right++;    left=2*i-right;    break; } else {    R[i]=R[j]; }

这样子,当当前flag位置的R[flag]求到后,再对flag为中心的回文子串S[flag]进行检查,同时更新回文右边的R[i],当出现半径长度超过以flag为中心字符串的范围时,更新flag到当前位置flag=right;,进入下一层循环,则flag到right之间的循环可以省略

  • 坑点:千万不要忘记!!!flag更新后,更新right和left时不要直接让right=flag一样的位置;而应该当R[j]超出范围,则right只向右移动一位,同时更新left,保持对称性,这样可以节省很多不必要的重复搜索

代码实现如下:
这里写图片描述

复杂度分析

对于这种算法的时间复杂度分析,本人不才,想法不是特别清晰,意识里猜测是O(n)的时间,具体证明方法未想到

阅读全文
0 0
原创粉丝点击