leetcode.5 Longest Palindromic Substring
问题描述:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd" Output: "bb"
思路:
根据回文的特性,我们可以以每一个字符为中心向外扩展进行查找。
注意要区分偶数长度情况与奇数长度情况:
1. 偶数长度的情况:对称轴不存在与具体字符而在回文字符串最中间的两字符中间:要检查s[i] == s[i+1]
2. 奇数长度情况:对称轴存在于某一字符,可以以当前字符作为轴,检查两边:s[i-1] == s[i+1]
在这里需要注意的边界问题是当给定字符串的长度小于2时:他们都不会进入到循环,会影响最后的结果,所以要单独处理一下。
时间复杂度为O(n2)
代码:
class Solution { public: string longestPalindrome(string s) { if(s.size() < 2) return s; int start = 0; int len = 0; for(int i = 0; i < s.size()-1; i++){ int left, right; //for even if(s[i] == s[i+1]){ left = i-1; right = i+2; int temp; searchPalindrome(s, left, right, temp); if(len < temp){ start = left+1; len = temp; } } //for odd; left = i-1, right = i+1; int temp; searchPalindrome(s, left, right, temp); if(len < temp){ start = left+1; len = temp; } } return s.substr(start, len); } void searchPalindrome(string s, int &left, int &right, int &ret){ while(left >= 0 && right < s.size()){ if(s[left] != s[right]){ break; } left--; right++; } ret = right-left-1; } };
其他解法:
参考链接:http://www.cnblogs.com/grandyang/p/4464476.html
1. 动态规划:
最不擅长动态规划,所以这里要好好学习记录一下~
dp的切入点是找到dp的递归式
对这个问题,首先建立一个二维的dp数组,d[j][i]存储的是从下标 j 到 i 的字符能否构成回文
可以对 i 和 j 的关系做一下分类:
1. i = j ( i 或 j 为同一字符串): dp[j][i] = 1 单一字符必定为回文
2. i - j < 2: (i 或 j 为相邻字符): dp[j][i] = s[i] == s[j]
3. i - j >= 2: (i 或 j 不为相邻字符): dp[j][i] = s[i] == s[j] && dp[j+1][i-1]
代码如下:
class Solution { public: string longestPalindrome(string s) { if(s.size() < 2) return s; int dp[s.size()][s.size()] = {0}; int left = 0, len = 1; for(int i = 0; i < s.size(); i++){ for(int j = 0; j < i; j++){ dp[j][i] = (s[i] == s[j] && (i-j < 2 || dp[j+1][i-1])); int temp = i - j + 1; if(dp[j][i] && len < temp){ left = j; len = temp; } } dp[i][i] = 1; } return s.substr(left, len); } };
时间复杂度O(n2) 空间复杂度O(n2)
表现并不如第一种方法,但是可以作为dp的例题进行学习。
2.马拉车算法:
马拉车算法第一遍看的时候我没有看懂,就一直放着了,今天我就再尝试一次,一定要搞懂它!