题目描述
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"输出: "bab"注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"输出: "bb"
题解
暴力法
暴力法将选出所有子字符串可能的开始和结束位置,并检验它是不是回文。
public class Solution{public string LongestPalindrome(string s){if (s.Length == 0) return "";var longest = s.Substring(0, 1);for (var i = 0; i < s.Length ; i++){var s1 = ExpandAroundCenter(s, i, i);if (s1.Length > longest.Length) longest = s1;var s2 = ExpandAroundCenter(s, i, i + 1);if (s2.Length > longest.Length) longest = s2;}return longest;}private string ExpandAroundCenter(string s, int left, int right){var l = left;var r = right;while (l >= 0 && r < s.Length && s[l] == s[r]){l--;r++;}return s.Substring(l + 1, r - (l + 1));}}
动态规划
参考:Grandyang
我们维护一个二维数组 dp,其中 dp[i,j] 表示字符串区间 [i, j] 是否为回文串。
当 i = j 时,只有一个字符,肯定是回文串
如果 i = j + 1,说明是相邻字符,此时需要判断 s[i] 是否等于 s[j]
如果 i 和 j 不相邻,即i - j >= 2时,除了判断 s[i] 和 s[j] 相等之外,dp[j + 1,i - 1] 若为真,就是回文串
通过以上分析,可以写出递推式如下:
dp[i,j] = true if i == j
= s[i] == s[j] if j = i + 1
= s[i] == s[j] && dp[i+1,j-1] if j > i + 1
public static string LongestPalindrome(string s){if (string.IsNullOrEmpty(s)) return "";// dp[i,j] 表示字符串区间 [i,j] 是否为回文串var dp = new bool[s.Length, s.Length];int left = 0, right = 0, len = 0;for (var i = 0; i < s.Length; i++){for (var j = 0; j < i; ++j){dp[j, i] = s[i] == s[j] && (i - j < 2 || dp[j + 1, i - 1]);if (dp[j, i] && len < i - j + 1){len = i - j + 1;left = j;right = i;}}dp[i, i] = 1!=0;}return s.Substring(left, right - left + 1);}
