题目
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
得到最长回文子串前,需要得到次最长子串。
例如字符串:cbbaabb ,它的最长回文子串为:bbaabb,得到该结果需要逐步确认: aa、baab 是回文,最终结论,bbaabb是回文子串。
类似此类需要依赖子问题结论的,求解都可以使用动态规划。
解题思路
有字符串:vxajkbbkja ,肉眼可判断最大回文为:ajkbbkja
如下图所示:我们只需要以中轴为起点,以途中红色箭头方向依次判断相等性,取到最长的即可。
(坐下部分对称,可以不必比较)
设横向为X, 纵向为Y,两个方向都从 字符v开始,字符a结束。延对称轴方向访问。
遍历如图红色箭头指向路径,如下每行对应一条红色箭头。
{0,0}
{1,0}
{1,1}{2,0}
{2,1}
{2,2}{3,1}
{3,2}
{3,3}{4,2}
{4,3}
{4,4}{5,3}
{5,4}
{5,5}{6,4}
{6,5}{7,4}{8,3}{9,2}
{6,6}{7,5}
{7,6}
{7,7}{8,6}
{8,7}
{8,8}{9,7}
{9,8}
{9,9}
最终得到相等的有点:{6,5}{7,4}{8,3}{9,2}
把它延对称轴映射:就可以得到最终的回文子串。
最终代码
我没有使用二维数组,所以节约了不少内存空间,由于增加了对特殊情况的判断,所以代码不是很简洁:
class Solution {
public String longestPalindrome(String s) {
char[] sArr = s.toCharArray();
/** 记录当前步、最长步的起始位置和长度 */
int maxLetf = 0, maxLen = 0, curLeft = 0, curLen = 0;
/** 记录当前步、最长步的起点是否在对称轴上,如果在对称轴上,回文长度为奇数,否则回文长度为偶数 */
boolean turnFlag = true, maxFlag = true;
/** returnValue 记录回溯的位置,可以认为它是对横坐标 i 值的缓存,
结合上一节,每条红线访问结束都需要回溯横坐标。 */
int returnValue = 0;
for(int i = 0; i < sArr.length;){
int j = (turnFlag) ? i : i - 1;
for(; j >= 0 && i < sArr.length; j--,i++){
if (sArr[i] == sArr[j]) curLen++;
else break;
}
/** 起点不在对称轴上,把最终长度加1 */
if (curLen != 0 && !turnFlag) curLen++;
/** 当起点在对称轴上的时候,最大步长相等即记录为最长 */
if (curLen > maxLen || (curLen == maxLen && turnFlag)){
maxLen = curLen;
maxLetf = curLeft;
maxFlag = turnFlag;
}
/** 因为依次访问,所以起点间次在或不在对称轴上 */
turnFlag = !turnFlag;
if (turnFlag) i = returnValue;
else i = ++returnValue;/** 前一次迭代不在对称轴上,下一次迭代起点在对称轴上,横坐标加1 */
curLeft = i;/** 重置迭代起点 */
curLen = 0;/** 清空步长 */
}
maxLetf = maxLetf - (--maxLen);
maxLen = maxFlag ? (maxLetf + maxLen + maxLen + 1) : (maxLetf + maxLen + maxLen);
return s.substring(maxLetf, maxLen);
}
}
设字符串长度为N,如下公式表示需要对比的次数,可以很直观的得到结论,时间复杂度就是二维表格一半格数近似和。
-
省略低次项和系数后:时间复杂度为:O(N^2)
-
因为没有使用二维数据:空间复杂度随求解字符串长度线性变化,复杂度为:O(N)。
利用本题同样思路,可以解两个字符串的最大公共子串,异曲同工。
排在我前边的应该都是马拉车算法大佬了。