Leetcode-5-最長回文子串

題目

image.png

和516題很像啊,要連著一起看http://www.itdecent.cn/p/d737ee489b95

題解

暴力解
列舉所有的子串,判斷是否為回文串,保存最長的回文串
超出時間限制

class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        // s[i,j] 是不是回文子串
        int len = 1;
        String res = s.substring(0, 1);  
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (solver(s, i, j)) {
                    // len = Math.max(len, (j - i) + 1);
                    if (len < (j-i+1)) {
                        len = j - i + 1;
                        res = s.substring(i, j+1);       // substring
                    }
                }
            }
        }
        return res;
    }
    private boolean solver(String s, int i, int j) {
        while (i < j) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}
題解1
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        // s[i,j] 是不是回文子串
        int len = 1;
        String res = "";  
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (solver(s, i, j)) {
                    // len = Math.max(len, (j - i) + 1);
                    if (len < (j-i+1)) {
                        len = j - i + 1;
                        res = s.substring(i, j+1);       // substring
                    }
                }
            }
        }
        return res;
    }
    private boolean solver(String s, int i, int j) {
        while (i < j) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}

結果


初始化改一下
String res = s.substring(0, 1);
或者

不過,改了之后的解答還是超出時間限制

題解2

dp


image.png

索引問題很麻煩,還是建議申請時用n

// dp[i,j]=dp[i+1,j-1]&&check(i,j)
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        int[][] dp = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            dp[i][i] = 1;
        }
        int res = 0;
        int start = 0;
        // 考慮dp[i+1,j-1]的合法性,i+1<j-1, i<j-2
        for (int i = n - 1; i > 0; i--) {     
            for (int j = n; j > i; j--) {
                // dp[i][j] = dp[i+1][j-1] && (s.charAt(i-1) == s.charAt(j-1));
                if (s.charAt(i-1) == s.charAt(j-1)) {     // 注意s的索引和dp的索引不同
                    // 排除dp[i][i+1]的情況
                    if (i < j-2) {
                        dp[i][j] = dp[i+1][j-1];
                    } else {
                        dp[i][j] = 1;
                    }
                }
                if (dp[i][j] == 1) {
                    if (j-i+1 > res) {
                        res = j-i+1;
                        start = i-1;     // 注意s的索引和dp的索引不同
                    }
                }
            }
        }
        return s.substring(start, start + res);      
    }
}

錯誤


image.png

初始化res=1

// dp[i,j]=dp[i+1,j-1]&&check(i,j)
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        int[][] dp = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            dp[i][i] = 1;
        }
        int res = 1;
        int start = 0;
        // 考慮dp[i+1,j-1]的合法性,i+1<j-1, i<j-2
        for (int i = n - 1; i > 0; i--) {     
            for (int j = n; j > i; j--) {
                // dp[i][j] = dp[i+1][j-1] && (s.charAt(i-1) == s.charAt(j-1));
                if (s.charAt(i-1) == s.charAt(j-1)) {     // 注意s的索引和dp的索引不同
                    // 排除dp[i][i+1]的情況
                    if (i < j-2) {
                        dp[i][j] = dp[i+1][j-1];
                    } else {
                        dp[i][j] = 1;
                    }
                }
                if (dp[i][j] == 1) {
                    if (j-i+1 > res) {
                        res = j-i+1;
                        start = i-1;     // 注意s的索引和dp的索引不同
                    }
                }
            }
        }
        return s.substring(start, start + res);      
    }
}
參考題解 (推薦)
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n<2) return s;
        int[][] dp = new int[n][n];
        for (int i=0; i<n; i++){
            dp[i][i] = 1;
        }
        int len=1;
        int start=0;
        //dp[i][j] = dp[i+1][j-1] s[i]==s[j]
        for (int i=n-2; i>=0; i--){
            for (int j=i+1; j<n; j++){
                if (s.charAt(i)==s.charAt(j)){
                    // j=i+1時,dp[i][j]應該是1,但是dp表計算的話就是0,需要特別處理
                    if (j-i<2) dp[i][j]=1;          // dp[i+1][j-1] 區(qū)間合法
                    else dp[i][j] = dp[i+1][j-1];
                }
                if (dp[i][j]==1 && (j-i+1>len)){
                    len = j-i+1;
                    start = i;
                }
            }
        }
        return s.substring(start, start+len);
    }
}
參考題解2
public class Solution {

    public String longestPalindrome(String s) {
        // 特判
        int len = s.length();
        if (len < 2) {
            return s;
        }

        int maxLen = 1;
        int begin = 0;

        // dp[i][j] 表示 s[i, j] 是否是回文串
        boolean[][] dp = new boolean[len][len];
        char[] charArray = s.toCharArray();

        for (int i = 0; i < len; i++) {
            dp[i][i] = true;
        }
        for (int j = 1; j < len; j++) {
            for (int i = 0; i < j; i++) {
                if (charArray[i] != charArray[j]) {
                    dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }

                // 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此時記錄回文長度和起始位置
                if (dp[i][j] && j - i + 1 > maxLen) {
                    maxLen = j - i + 1;
                    begin = i;
                }
            }
        }
        return s.substring(begin, begin + maxLen);
    }
}

參考

https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容