力扣每日一题(leetcode:最长回文子串)

每日一道编程题,今日继续!

1. 最长回文子串

图片

Think first

请耐心的自己先想一想

我们这么想,一个字母肯定是回文,两个相同的字母也是回文。在此基础上最左和最右添加相同的字母得到的字符串也是回文。因此这是一个动态规划问题,我们首先默认字符串的每一个长度为1的子串都是回文,然后设长度为2...直到n,判断相应长度下的子串是否是回文。怎么判断呢,若字符串收尾不同,则非回文;若相同,则该子串是否是回文=去掉首尾的子串是否是回文。递归判断

JAVA版本:

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];

        // 初始化:所有长度为 1 的子串都是回文串

        for (int i = 0; i < len; i++) {

            dp[i][i] = true;

        }

        char[] charArray = s.toCharArray();

        // 递推开始

        // 先枚举子串长度

        for (int L = 2; L <= len; L++) {

            // 枚举左边界,左边界的上限设置可以宽松一些

            for (int i = 0; i < len; i++) {

                // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得

                int j = L + i - 1;

                // 如果右边界越界,就可以退出当前循环

                if (j >= len) {

                    break;

                }

                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][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置

                if (dp[i][j] && j - i + 1 > maxLen) {

                    maxLen = j - i + 1;

                    begin = i;

                }

            }

        }

        return s.substring(begin, begin + maxLen);

    }

}

C++:

#include

#include

#include

using namespace std;

class Solution {

public:

    string longestPalindrome(string s) {

        int n = s.size();

        if (n < 2) {

            return s;

        }

        int maxLen = 1;

        int begin = 0;

        // dp[i][j] 表示 s[i..j] 是否是回文串

        vector<vector> dp(n, vector(n));

        // 初始化:所有长度为 1 的子串都是回文串

        for (int i = 0; i < n; i++) {

            dp[i][i] = true;

        }

        // 递推开始

        // 先枚举子串长度

        for (int L = 2; L <= n; L++) {

            // 枚举左边界,左边界的上限设置可以宽松一些

            for (int i = 0; i < n; i++) {

                // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得

                int j = L + i - 1;

                // 如果右边界越界,就可以退出当前循环

                if (j >= n) {

                    break;

                }

                if (s[i] != s[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][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置

                if (dp[i][j] && j - i + 1 > maxLen) {

                    maxLen = j - i + 1;

                    begin = i;

                }

            }

        }

        return s.substr(begin, maxLen);

    }

};

Python:

class Solution:

    def longestPalindrome(self, s: str) -> str:

        n = len(s)

        if n < 2:

            return s

        max_len = 1

        begin = 0

        # dp[i][j] 表示 s[i..j] 是否是回文串

        dp = [[False] * n for _ in range(n)]

        for i in range(n):

            dp[i][i] = True

        # 递推开始

        # 先枚举子串长度

        for L in range(2, n + 1):

            # 枚举左边界,左边界的上限设置可以宽松一些

            for i in range(n):

                # 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得

                j = L + i - 1

                # 如果右边界越界,就可以退出当前循环

                if j >= n:

                    break

                if s[i] != s[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][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置

                if dp[i][j] and j - i + 1 > max_len:

                    max_len = j - i + 1

                    begin = i

        return s[begin:begin + max_len]

该解时间和空间复杂度均为n的平方。

不要只看不做哦,勤动手才能得到真正的训练,看完题解后务必自己在写一遍!加油!

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值