动画演示LeetCode算法题:005-最长回文子串,多种实现方式

题目:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例1:

输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例2:

输入: “cbbd”
输出: “bb”

分析

首先什么是回文字符串?回文字符串就是整个字符串以中轴对称的字符串,比如:“abcdcba”、"abba"都是回文字符串。毫无疑问空字符串和长度为1的字符串都是回文字符串。
如果要判断一个字符串是不是回文字符串,只需要从字符串的中间向两边遍历并且判断对应位置的字符相等即可。字符串长度为奇数时,最中间的那个字符就是起始位置,如果字符串长度为偶数,最中间的两个字符就是起始位置。

最笨的解法

要想在字符串中找到最大的回文子串,最笨的办法,也是最容易想到的办法肯定是循环遍历。我们可以遍历出字符串每一个字符为中心的回文子串,在这些全部的子串中找到长度最长的即可。这种笨办法的时间复杂度为O(n^2)。
实现代码如下:

利用数组缓存回文状态

上面的方法是双层循环遍历所有的回文字符串,然后通过比较他们的长度,找到最长的那个。我们还可以创建一个二维数组temp[][],temp[i][j]表示区间[j,i]是不是回文字符串。
那么我们就可以有如下的递推:

  • i == j时表示的是单个字符,所以有temp[i][j] = true;
  • i == j + 1时表示的是相邻字符,所以有i,j字符相等时temp[i][j] = true,否则temp[i][j] = false;
  • i > j + 1时,我们只需要知道区间[j + 1, i - 1]是否是回文字符串,如果不是那么temp[i][j]肯定也不是,如果是,那么再判断i、j字符串是否相等。

根据上面的递推实现的代码如下:

下面是字符串"babad"的执行过程:

O(n)的解法

第一种方法是双层循环求解的,所以时间复杂度肯定是O(n2)的。第二种方法也是有两层循环,虽然内循环不是完整的n,但时间复杂度还是O(n2)的。
那么有没有时间复杂度为O(n)的解法呢?显然是有的。
下面是实现的代码:

更多LeetCode文章:
https://github.com/ybjx/Leetcode

扫码关注
头条号:  微信公众号:

你可能感兴趣的:(LeetCode)