[Leetcode]_5 Longest Palindromic Substring

/**
 *  Index: 5
 *  Title: Longest Palindromic Substring
 *  Author: ltree98
 **/

如果,str 是一个回文串,那么去掉str的头和尾,它也是一个回文串:
比如 abcba -> bcb -> c
所以,这题可通过动态规划来解。

// DP
class Solution {
public:
    string longestPalindrome(string s) { 
        int len = s.length();
        bool temp[1001][1001] = {0};

        int startSPos = 0;
        int longestPaliLen = 1;

        for(int i = len - 1 ; i >= 0 ; i--)    {
            temp[i][i] = true;
            if( i > 0 and s[i - 1] == s[i] )    {
                temp[i-1][i] = true;
                startSPos = i - 1;
                longestPaliLen = 2;
            }
        }

        for(int pLen = 3 ; pLen <= len ; pLen++) {
            for(int j = len - 1; j >= 0 ; j--)  {
                int i = j - pLen + 1;
                if(i < 0)
                    break;

                if( temp[i+1][j-1] == true and s[i] == s[j] )  {
                    temp[i][j] = true;
                    startSPos = i;
                    longestPaliLen = pLen;
                }
            }
        }

        return s.substr(startSPos, longestPaliLen);
    }
};



下面这种解法的亮点在于标记 key 的那部分;
它将重复的字母跳过(因为他们一定是回文),
并且能找到以这段重复字母为中心的的最长回文串,
之后,
还让下一个查找坐标直接拉到这段重复的回文串之后。

class Solution {
public:
    string longestPalindrome(string s) { 
        int len = s.length();
        if(len == 1)    
            return s;

        int startPos = 0, longestPaliLen = 1;
        for(int i = 0; i < len; )    {
            int sPos = i, ePos = i;

            // key
            while(ePos < len-1 && s[ePos+1] == s[ePos])
                ePos++;

            i = ePos+1;
            while(ePos < len-1 && sPos > 0 && s[ePos+1] == s[sPos-1])   {
                sPos--;
                ePos++;
            }

            int newLen = ePos - sPos + 1;
            if(newLen > longestPaliLen) {
                startPos = sPos;
                longestPaliLen = newLen;
            }
        }

        return s.substr(startPos, longestPaliLen);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值