You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

最长回文子串代码异常排查:输入"aaaaa"仅返回长度3的结果

最长回文子串问题调试:输入"aaaaa"返回长度3的问题分析

我在解决最长回文子串问题时,输入"aaaaa"后代码返回的最长回文子串长度只有3,不符合预期。我的思路是维护一个dp数组:

  • 长度为1的子串设为1(表示是回文)
  • 长度为2且两端字符相同的子串设为1
  • 其余情况仅当s[i]==s[j]且dp[i+1][j-1]==1时,才将dp[i][j]设为1

我的代码如下:

class Solution {
    public:
        string longestPalindrome(string s) {
            int n = s.size();
            int dp[n][n];
            int fini=0,finj=0;
            for(int i=0; i<s.size(); i++)
                for(int j=0; j<s.size(); j++){
                    if(i==j)
                            dp[i][j]=1;
                    else
                        dp[i][j]=0;
                }
            for(int i=0; i<s.size()-1; i++){
                    if(s[i]==s[i+1]){
                        dp[i][i+1]=1;
                        fini = i;
                        finj = i+1;
                        
                    }
            }
            //cout<<dp[1][6];
            cout<<fini<<finj<<endl;
            for(int i=0; i<s.size()-1; i++){
                for(int j=i+1; j<s.size(); j++){
                    cout<<"dp"<<" "<<i<<" "<<j<<' '<<dp[i][j]<<" "<<dp[i+1][j-1]<<endl;
                    if(s[i]==s[j] && dp[i+1][j-1]){
                            dp[i][j]=1;
                            if(abs(j-i+1)>abs(finj-fini+1)){
                                fini=i;
                                finj=j;
                            }
                                    cout<<fini<<" "<<finj<<endl;
    
                        }
                    
                    }     
                                
                }
            
            return s.substr(fini, finj-fini+1);
        }
    };

问题根源

你的dp数组遍历顺序错误。当前代码按i从小到大、j从i+1到末尾的顺序遍历,会导致处理长串时,内部依赖的短串状态还没被计算。比如处理i=0,j=4(整个"aaaaa")时,dp[1][3]还没被赋值为1——因为i=1,j=3的遍历要等到i=0的循环结束后才执行,此时判断条件不成立,dp[0][4]无法被设为1,自然无法更新最长回文的范围。

修正方案

正确的遍历顺序应该是按子串长度从小到大处理:先处理长度1,再长度2,接着从长度3到n依次处理。这样当计算长度为l的子串时,所有长度为l-2的子串(即dp[i+1][j-1]对应的子串)已经被正确计算过。

修正后的代码:

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        if (n == 0) return "";
        bool dp[n][n];
        memset(dp, 0, sizeof(dp));
        int fini = 0, finj = 0;

        // 初始化长度为1的子串
        for (int i = 0; i < n; ++i) {
            dp[i][i] = true;
        }

        // 处理长度为2的子串
        for (int i = 0; i < n - 1; ++i) {
            if (s[i] == s[i+1]) {
                dp[i][i+1] = true;
                fini = i;
                finj = i+1;
            }
        }

        // 处理长度>=3的子串,l为子串长度
        for (int l = 3; l <= n; ++l) {
            for (int i = 0; i <= n - l; ++i) {
                int j = i + l - 1; // 子串右端点
                if (s[i] == s[j] && dp[i+1][j-1]) {
                    dp[i][j] = true;
                    // 更新最长回文范围
                    if (j - i + 1 > finj - fini + 1) {
                        fini = i;
                        finj = j;
                    }
                }
            }
        }

        return s.substr(fini, finj - fini + 1);
    }
};

额外优化点

  1. 把int类型的dp数组改成bool类型,更贴合回文的判断逻辑,同时用memset初始化避免栈数组的未初始化垃圾值问题。
  2. 增加了n=0的边界处理,避免空字符串输入时出错。

内容的提问来源于stack exchange,提问作者Somyadeep Shrivastava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:20:37