【问题标题】:[leetcode 5 ]Can't really find what's wrong in my solution for longest Palindrome substring problem[leetcode 5] 在我的最长回文子串问题的解决方案中找不到问题所在
【发布时间】:2020-11-25 06:45:26
【问题描述】:

输入:

babad
abbd

输出:

ad
bb

预期:

bab
bb

代码:

#include<iostream>
using namespace std;

class Solution {
public:
    string longestPalindrome(string s) {
        int maxlength=1;
        bool ispalindromic[1000][1000]={false};
        for(int i=0;i<s.length();i++)
            ispalindromic[i][i]=1;
                
        for(int l=2;l<s.length();l++){
            for(int i=0;i<s.length()-1; i++){
                int j=i+l-1;
                if(l==2&&s[i]==s[j]){
                    ispalindromic[i][j]=1;
                    maxlength=max(maxlength,j-i+1);
                    continue;}
                if(ispalindromic[i+1][j-1]&&s[i]==s[j]){
                    ispalindromic[i][j]=1;
                    maxlength=max(maxlength,j-i+1);
                }
            }}
        for(int i=0;i<s.length();i++){
        int j=i+maxlength-1;
            if(ispalindromic[i][j]){
                return s.substr(i,j);
            }
        }
        return s.substr(0,1);
    }
};

我首先创建了ispalindromic[1000][1000],并确保每个字母本身都是回文。然后我从 2 的长度开始检查回文,依此类推。每当ispalindromic 变为真时,代码就会更新maxlength,这样最后代码就可以简单地使用maxlength 打印最长的回文。

【问题讨论】:

  • 这里有点离题,应该在codereview 上提问。如果您希望有人通过查看您的代码来搜索逻辑错误,那么它的格式应该是合理的。
  • 您似乎从未考虑过整个字符串可能是回文,请尝试使用rotor进行测试

标签: c++ algorithm debugging dynamic-programming palindrome


【解决方案1】:

这段代码有一些问题。

  1. for 循环的索引 当您考虑可能的子字符串的长度 l 时,您的 l 应该介于 2 到 s.length() 之间,因此外部 for 循环应该是:

    for(int l=2;l&lt;=s.length();l++){ 你看我把l &lt; s.length() 改成了l &lt;= s.length()

  2. 那么你的i内循环索引应该从0s.length()-l,当你考虑一个长度为l的字符串时,它不能比这更远。需要修改为:

    for(int i=0;i&lt;s.length()-l+1; i++){

  3. 那么l=2if条件应该修改为:

              if(l==2){
                 if ( s[i] == s[j] ) {
                  ispalindromic[i][j]=1;
                   maxlength=max(maxlength,j-i+1);
                 }
    
                 continue;
             }
    

    您需要将s[i] == s[j] 移动到if 内,因为无论s[i] == s[j] 如何,您都需要按照您的代码继续。

  4. 您需要打印跨越 maxlength 长度的子字符串,因此您的返回语句应该是:return s.substr(i,maxlength);

通过这些更正,代码为:

class Solution {
public:
    string longestPalindrome(string s) {
        int maxlength = 1;
        bool ispalindromic[1000][1000] = {false};

        for (int i = 0; i < s.length(); i++) {
            ispalindromic[i][i] = 1;
        }

        for (int l = 2; l <= s.length(); l++) {
            for (int i = 0; i < s.length() - l + 1; i++) {
                int j = i + l - 1;

                if (l == 2) {
                    if ( s[i] == s[j] ) {
                        ispalindromic[i][j] = 1;
                        maxlength = max(maxlength, j - i + 1);
                    }

                    continue;
                }

                if (ispalindromic[i + 1][j - 1] && s[i] == s[j]) {
                    ispalindromic[i][j] = 1;
                    maxlength = max(maxlength, j - i + 1);
                }
            }
        }

        for (int i = 0; i < s.length(); i++) {
            int j = i + maxlength - 1;

            if (ispalindromic[i][j]) {
                return s.substr(i, maxlength);
            }
        }

        return s.substr(0, 1);
    }
};

【讨论】:

  • 3.但是下一个if 会是假的 4. 为什么不能是j?
  • @JacksonSteel - 3. 对于l = 2j = i + 1 对吗?假设s[i] != s[j] 然后if ( l == 2 &amp;&amp; s[i] == s[j] ) 失败,如果有ispalindromic[i+1][i+1-1] = ispalindromic[i+1][i] 将被检查,那就是你真正想要的吗? 4. 在 c++ 中,substr 是子字符串,它是从字符位置 pos 开始并跨越 len 个字符(或直到字符串末尾,以先到者为准)的对象部分。如果你通过 j 它将跨越 j 字符从 i 这不是你想要的。你想跨越maxlength 字符从i
  • 3. spalindromic[i+1][i+1-1] = ispalindromic[i+1][i] 是假的,对吧?
  • @JacksonSteel,如果 s[i] == s[i+1] 可能是真的,但这不是你想要去的方向,因为你正在为每个长度逐步构建表格,您将考虑 i 的情况
【解决方案2】:

不确定您面临的问题。 This answer 是正确的,解决您的问题。

除此之外,这也将通过并且同样是一种动态编程方法,就像你的一样:

#include <cstdint>
#include <string>

const static struct Solution {
    using SizeType = std::uint_fast16_t;
    static std::string longestPalindrome(const std::string s) {
        const SizeType slen = std::size(s);

        if (slen < 2) {
            return s;
        }

        SizeType maxlen = 0;
        SizeType head = 0;
        SizeType curr = 0;

        while (curr < slen) {
            SizeType left = curr;
            SizeType right = curr;

            while (right < slen - 1 and s[right] == s[-~right]) {
                ++right;
            }

            curr = -~right;

            while (right < slen - 1 and left > 0 and s[-~right] == s[left - 1]) {
                ++right;
                --left;
            }

            SizeType templen = -~right - left;

            if (templen > maxlen) {
                head = left;
                maxlen = templen;
            }
        }

        return s.substr(head, maxlen);
    }
};


// -~x is simply x + 1;

参考文献

  • 更多详细信息,请参阅Discussion Board,您可以在其中找到大量解释清楚且公认的解决方案,其中有多种languages,包括高效算法和渐近time/space 复杂性分析1,2.

【讨论】:

  • 请解释原始代码有什么问题以及如何修复它。仅仅发布新代码并不能提供丰富的信息。
  • 看起来你的代码是一个完全不同的算法,它实际上并没有解决原始代码中的问题。
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多