LeetCode OJ5 Longest Palindromic Substring 小结

Longest Palindromic Substring

问题描述

最长回文字串

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

解题思路

一开始, 我们想到的思路是, 通过首末两个指针, 依次移动末尾指针, 判断以首指针为起始的字符串时候为 回文串, 并记录相应的最长字串的首末位置及其长度
算法复杂度为 O(n2)
很不幸的是, 这种方法 TLE 了。

于是, 我们采用了另一种方法, 指针cur从头向后移动, 如果s[cur] == s[cur + 1] || s[cur] == s[cur + 2], 说明形成回文字串了, 记录当前的cur值, 并试图扩展回文串, 获取最大回文字串

My Code AC

class Solution {
public:
    void getPalindromic(const string & s, int pcur_begin, int pcur_end, int & g_begin, int & g_end, int & len)
    {
        while (pcur_begin != 0 && pcur_end != s.size() - 1 && s[--pcur_begin] == s[++pcur_end]);
        // s[pcur_begin] != s[pcur_end] 此时, pcur_begin 落在其实字符的前一个字符, pcur_end 在结束字符的后一个字符

        if (s[pcur_begin] != s[pcur_end] && len < pcur_end - pcur_begin - 1)
        {
            len = pcur_end - pcur_begin - 1;
            g_begin = pcur_begin + 1;
            g_end = pcur_end - 1;
        }

        if (s[pcur_begin] == s[pcur_end] && len < pcur_end - pcur_begin + 1)
        {
            len = pcur_end - pcur_begin + 1;
            g_begin = pcur_begin;
            g_end = pcur_end;
        }
    }

    string longestPalindrome(string s) {
        if (s.size() <= 1)
            return s;

        int len = 0;
        int g_begin = 0;
        int g_end = 0;

        for (int cur = 0; cur != s.size(); cur++)
        {
            if (s[cur] == s[cur + 1])
            {
                int pcur_begin = cur;
                int pcur_end = cur + 1;
                getPalindromic(s, pcur_begin, pcur_end, g_begin, g_end, len);
            }

            if (s[cur] == s[cur + 2])
            {
                int pcur_begin = cur;
                int pcur_end = cur + 2;
                getPalindromic(s, pcur_begin, pcur_end, g_begin, g_end, len);
            }
        }

        return string(s.begin() + g_begin, s.begin() + g_end + 1);
    }
};

大神们的代码

demo1

大神的思路与我们的总体一致, 不过, 在对重复字符的操作上, 大神明显简练, 并且我们的代码中由于 s[pcur_begin]==s[++pcur_end] 的存在, 无形中降低了代码的可读性, 并且在失败的时候, 又一次执行了++操作, 和我们的预期不太一致, 这种写法需要避免
另外 substr方法, 值得借鉴

string longestPalindrome(string s) {
    if (s.empty()) return "";
    if (s.size() == 1) return s;
    int min_start = 0, max_len = 1;
    for (int i = 0; i < s.size();) {
      if (s.size() - i <= max_len / 2) break;
      int j = i, k = i;
      while (k < s.size()-1 && s[k+1] == s[k]) ++k; // Skip duplicate characters.
      i = k+1;
      while (k < s.size()-1 && j > 0 && s[k + 1] == s[j - 1]) { ++k; --j; } // Expand.
      int new_len = k - j + 1;
      if (new_len > max_len) { min_start = j; max_len = new_len; }
    }
    return s.substr(min_start, max_len);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值