Leetcode 05最长回文子串(c++和python)

题目描述:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 的最大长度为1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

解题思路:

简单直观的解法,回文是中心对称的,所以从第二个字符开始,判断是否是中心对称。

执行用时:12 ms, 在所有 C++ 提交中击败了95.47%的用户

内存消耗:7 MB, 在所有 C++ 提交中击败了89.26%的用户

C++代码:

class Solution {
public:
	string longestPalindrome(string s) {
        // 找到回文开始的索引start,和回文的长度max_len.

		int s_len = s.size();
        int start_idx = 0; // 最长回文开始的索引start
        int max_len = 0;  // 最长回文长度。
        // 1. 如果长度小于等于1,则字符串本身
        if (s_len <= 1) return s;
        // 2. 因为回文是对称的,从第二项开始,判断左右是否对称
        // 以i-1和i为中心的偶数长度回文,或者以i为z中中心的奇数长度回文
        for (int i = 1; i < s_len; i++)
        {
            // 3. 找是否有偶数长度的回文,向两边扩展,找到最左边索引low和最右边索引high
            int low = i-1, high=i;  // 初始时回文左右两边索引是i-1和i. abb
            while (0 <= low && high < s_len && s[low] == s[high])  // 左右不越界,并且字符相等
            {
                low--;
                high++;  // 符合以上两个条件,则更新回文的左右索引
            }
            // 找到后更新start_idx和max_len
            low++;  //上面多移动了一位
            high--;
            if (high - low + 1 > max_len) 
            {
                start_idx = low;
                max_len = high - low + 1;
            }

            // 找是否有奇数长度的回文,向两边扩展,找到最左边索引low和最右边索引high
            low = i-1, high = i+1;   // 回文中间索引是i,初始时两边索引是i-1和i+1. aba
            while (0 <= low && high <= s_len && s[low] == s[high])  
            {
                low--;
                high++;
            }
            // 找到后更新start_idx和max_len
            low++;
            high--;
            if (high - low + 1 > max_len) 
            {
                start_idx = low;
                max_len = high - low + 1;
            }
        }
        return s.substr(start_idx, max_len);
	}
};

简化版:

class Solution {
public:
    string longestPalindrome(string s) {
        // 回文是中心对称的
        if (s.size() <= 1) return s;
        int max_len = 0;
        int start_idx = 0;

        for (int i = 1; i < s.size(); i++)  // 以i-1和i为中心的偶数长度回文,或者以i为z中中心的奇数长度回文
        {
            // 查看是否有偶数长度的回文,有则会更新max_len和start_idx
            int low = i - 1, high = i; // 如果是偶数,中心对称,往两边扩展. abb
            huiwen_idx(s, low, high, max_len, start_idx);
            

            // 查看是否有奇数长度回文,有则会更新max_len和start_idx
            low = i-1; high = i+1;
            huiwen_idx(s, low, high, max_len, start_idx);
        }
        return s.substr(start_idx, max_len);
    }

    void huiwen_idx(string s, int low, int high, int &max_len, int &start_idx)
    {
        while (0 <= low && high < s.size() && s[low] == s[high])
        {
            low--;
            high++;
        }
        low++;
        high--;
        // 确认是否需要更新
        if (max_len < (high-low+1))
        {
            max_len = high - low + 1;
            start_idx = low;
        }
    }
};

 

对应的Python解法

python代码:

执行用时:444 ms, 在所有 Python 提交中击败了94.00%的用户

内存消耗:13.1 MB, 在所有 Python 提交中击败了79.54%的用户

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        # 1, 长度为0或者1
        s_len = len(s)
        if s_len <= 1: 
            return s 
        # 获取最长回文开始的索引start_idx,和长度max_len
        
        start_idx = 0
        max_len = 0
        for i in range(1, s_len):
            # 2. 偶数回文中间位置是i-1, i
            low = i-1
            high = i
            while 0 <= low and high < s_len and s[low] == s[high]:
                low = low - 1
                high = high + 1
            low = low + 1  # 回到真实的回文左右索引
            high = high -1 
            # 判断长度是否比之前记录的长
            if high-low+1 > max_len:
                start_idx = low
                max_len = high - low + 1
            
            # 3.奇数回文中间位置是i
            low = i-1
            high = i+1
            while 0 <= low and high < s_len and s[low] == s[high]:
                low = low - 1
                high = high + 1
            low = low + 1
            high = high - 1
            if high-low+1 > max_len:
                start_idx = low
                max_len = high - low + 1
        
        return s[start_idx:start_idx+max_len]



        

根据提供的引用内容,有三种方法可以解决LeetCode上的最长回文子串问题。 方法一是使用扩展中心法优化,即从左向右遍历字符串,找到连续相同字符组成的子串作为扩展中心,然后从该中心向左右扩展,找到最长的回文子串。这个方法的时间复杂度为O(n²)。\[1\] 方法二是直接循环字符串,判断子串是否是回文子串,然后得到最长回文子串。这个方法的时间复杂度为O(n³),效率较低。\[2\] 方法三是双层for循环遍历所有子串可能,然后再对比是否反向和正向是一样的。这个方法的时间复杂度也为O(n³),效率较低。\[3\] 综上所述,方法一是解决LeetCode最长回文子串问题的最优解法。 #### 引用[.reference_title] - *1* [LeetCode_5_最长回文子串](https://blog.csdn.net/qq_38975553/article/details/109222153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Leetcode-最长回文子串](https://blog.csdn.net/duffon_ze/article/details/86691293)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [LeetCode 第5题:最长回文子串Python3解法)](https://blog.csdn.net/weixin_43490422/article/details/126479629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值