Skip to content
本页目录

0005-最长回文子串

https://leetcode.cn/problems/longest-palindromic-substring

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成

基本思路:双指针法

遍历字符串s,从 i 开始两边检测是否是回文,是的话,就扩展 l 和 r,如果超过当前回文串的长度就覆盖当前回文串 注意双位和单位的检测方法不一样, 双位 i,i+1 往两边扩展,单位 i-1,i+1往两边扩展

参考代码

csharp
public class Solution {
    public string LongestPalindrome(string s) {
    	string pd = s[0].ToString();
    	int l,r;
        
        //偶数回文
    	for(int i=0; i<s.Length-1; i++){
    		l = i;
    		r = i+1;
            while(l>=0 && r<s.Length && s[l] == s[r]){
                string newPd = s.Substring(l,r-l+1);
    			if(newPd.Length > pd.Length){
    				pd = newPd;
    			}
                l--;
                r++;
            }
    	}
		//奇数回文
    	for(int i=0; i<s.Length-1; i++){
    		l = i-1;
    		r = i+1;
            //单位
    		while(l>=0 && r<s.Length && s[l] == s[r]){
    			string newPd = s.Substring(l,r-l+1);
    			if(newPd.Length > pd.Length){
    				pd = newPd;
    			}
                l--;
                r++;
    		}
    	}
    	return pd;
    }
}

参考代码2:优化 偶数 和 奇数

csharp
public class Solution {

	string pd;

	private void ExpandCenter(int l, int r, string s){
		while(l>=0 && r<s.Length && s[l] == s[r]){
            string newPd = s.Substring(l,r-l+1);
			if(newPd.Length > pd.Length){
				pd = newPd;
			}
            l--;
            r++;
        }
	}
	
    public string LongestPalindrome(string s) {
    	pd = s[0].ToString();
        //偶数
    	for(int i=0; i<s.Length-1; i++){
    		ExpandCenter(i,i+1,s);
    	}
        //奇数
    	for(int i=0; i<s.Length-1; i++){
    		ExpandCenter(i-1,i+1,s);
    	}
    	return pd;
    }
}

基本思路2: 动态规划

dp[i,j] 表示字符串s的第i到第j个字母组成的串是否为回文串 dp[i,j] = true 如果 s[i..j]是回文串,其他情况则是 false 如 s[i..j] 不是回文串,或者 i>j 此时 s[i..j]不合法

dp[i,j] = dp[i+1,j-1] ^ (s[i] == s[j]) 注意此处的 dp[i+1,j-1] 是往里面收缩 边界条件:dp[i,i] = true 单个字符自己就组成回文串, dp[i,i+1] = (s[i] == s[j]) 双数,就看两个是否相等

csharp
//TODO
public class Solution {	
    public string LongestPalindrome(string s) {
    	bool[,] dp = new bool[s.Length,s.Length];
    	//初始化边界
    	//length = 1
    	for(int i=0; i<s.Length; i++){
    		dp[i,i] = true;
    	}
    	int begin = 0;
    	int maxLength = 1;
    	for(int len = 2; len <= s.Length; len++){
    		for(int i=0; i<s.Length; i++){
    			int j = len + i -1;
    			if(j >= s.Length){
    				break;
    			}
    			if(s[i] == s[j]){
    				if(j - i < 3){ //2位或者3位
    					dp[i,j] = true;
    				}
    				else{
    					dp[i,j] = dp[i+1,j-1];
    				}
    			}
    			else{
    				dp[i,j] = false;
    			}
    			//统计当前长度
    			if(dp[i,j] && j - i +1 > maxLength){
    				maxLength = j-i+1;
    				begin = i;
    			}
    		}
    	}
    	return s.Substring(begin,maxLength);
    }
}

复习:动态规划:20220615

csharp
public class Solution {
    public string LongestPalindrome(string s) {
        //动态规划
        int n = s.Length; 
        bool[,] dp = new bool[n,n];
        string result = "";
        //状态转移
        for(int i=n-1;i>=0;i--){
            for(int j=i;j<n;j++){
                if(j-i<=1){
                    dp[i,j] = s[i] == s[j];
                }
                else{
                    dp[i,j] = s[i] == s[j] && dp[i+1,j-1];
                }
                if(dp[i,j] && j-i+1 > result.Length){
                   result = s.Substring(i,j-i+1);
                }
            }
        }
        return result;
    }
}

Released under the MIT License.