[LeetCode] 5 Longest Palindromic Substring
题目地址:
https://leetcode.com/problems/longest-palindromic-substring/description/
题目:
其实就是求一个字符串的最长回文子字符串。
解法:
我首先采取了暴力解法,不出意料地TLE了。这是超时的TLE解法:
class Solution { public: string longestPalindrome(string s) { if (s.size() == 0) return ""; string str; string longest; int max = 0; for (int i = 0; i < s.size(); i++) { str = ""; for (int j = i; j < s.size(); j++) { str += s[j]; if (isPalindrome(str) && str.size() > max) { longest = str; max = str.size(); } } } return longest; } bool isPalindrome(string s) { for (int i = 0; i < s.size() / 2; i++) { if (s[i] != s[s.size() - i - 1]) return false; } return true; } };
这类题目一看就是用动态规划解决的问题。我们可以使用一个二维布尔数组dp[i][j]来表示字符串s从i到j这个子字符串是否一个子字符串。
它的状态转移方程是这样的:
i == j :dp[i][j] = true
j - i == 1:if (s[i] == s[j]) dp[i][j] = true
else dp[i][j] = false
j - i >= 1: if (s[i] == s[j] && dp[i + 1][j - 1]) dp[i][j] = true
else dp[i][j] = false
由于递推的时候dp[i][j]需要看dp[i + 1][j - 1]的值,因此要注意循环中i和j的变化顺序。
代码如下:
class Solution { public: string longestPalindrome(string s) { bool ispalindrome[s.size()][s.size()] = {false}; int left, right, len = -1; for (int i = s.size(); i >= 0; i--) { for (int j = i; j < s.size(); j++) { if (i == j) ispalindrome[i][j] = true; else if (j - i == 1) ispalindrome[i][j] = s[i] == s[j] ? true : false; else ispalindrome[i][j] = (s[i] == s[j] && ispalindrome[i + 1][j - 1]) ? true : false; if (ispalindrome[i][j] && j - i + 1 > len) { len = j - i + 1; left = i; right = j; } } } return s.substr(left, right - left + 1); } };