LeetCode5 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, and there exists one unique longest palindromic substring. (Medium)
分析:
采用动态规划,dp[i][j]表示从s[i]到s[j]的字串是否回文,然后按照字串长度进行遍历,如果s[i] == s[j] && dp[i + 1][j - 1] == 1,则dp[i][j] = 1
并更新起始位置和最大长度。
初始化除了要将dp[i][i] i=0,1,2...n-1初始化外,还需要初始化dp[i][i+1]
最终得到维护好的最大字串起始位置和长度,返回该字串。
代码:
1 class Solution { 2 public: 3 string longestPalindrome(string s) { 4 int dp[1005][1005] = {0}; 5 int start = 0, length = 1; 6 for (int i = 0; i < s.size(); ++i) { 7 dp[i][i] = 1; 8 } 9 for (int i = 0; i < s.size() - 1; ++i) { 10 if (s[i] == s[i + 1]) { 11 dp[i][i + 1] = 1; 12 start = i; 13 length = 2; 14 } 15 } 16 for (int k = 2; k < s.size(); ++k) { 17 for (int i = 0; i < s.size() - k; ++i) { 18 if (s[i] == s[i + k] && dp[i + 1][i + k - 1] == 1) { 19 dp[i][i + k] = 1; 20 start = i; 21 length = k + 1; 22 } 23 } 24 } 25 return s.substr(start,length); 26 } 27 };
时间复杂度 O(n^2), 空间复杂度 O(n^2);
解法2:
考虑不采用dp数组,节省空间复杂度为O(1);
对每个每个节点作为初始位置,利用helper函数,开始向外扩展,如果满足s[left] == s[right], left--; right++继续判定;
直到不满足条件位置或边界,并更新最大长度和初始位置。
注意拓展节点时除了拓展单一节点情况,还需要拓展两个节点开始的情况 (与dp的初始化条件类似);
代码:
1 class Solution { 2 private: 3 int helper(const string& s, int left, int right) { 4 int length = 0; 5 while (left >= 0 && right < s.size() && s[left] == s[right]) { 6 length = right - left + 1; 7 left--; 8 right++; 9 } 10 return length; 11 } 12 public: 13 string longestPalindrome(string s) { 14 int start = 0, length = 0; 15 for (int i = 0; i < s.size() ; ++i) { 16 int l1 = helper(s, i, i); 17 if (l1 > length) { 18 length = l1; 19 start = i - (length / 2); 20 } 21 } 22 for (int i = 0; i < s.size() - 1; ++i) { 23 int l2 = helper(s, i, i+1); 24 if (l2 > length) { 25 length = l2; 26 start = i - (length - 2) / 2; 27 } 28 } 29 return s.substr(start, length); 30 } 31 };