[leetcode刷题 C++] 5. Longest Palindromic Substring

[leetcode刷题 C++] 5. 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.

    Example 1:

     Input: "babad"
     Output: "bab"
     Note: "aba" is also a valid answer.
    

    Example 2:

     Input: "cbbd"
     Output: "bb"
    
  • 思路
    有两种方法:

    • 利用回文对称的特点
    • 动态规划
  1. 回文的特点是字符串是以某个中心对称的。如example中的例子,对称有两种情况:一种是以一个字符对称(如,“bab”),另一种是以两个相同的字符为对称的中心(如,“cbbc”)。 使用2个变量来记录,中心和步长:

    class Solution {
    public:
    	string longestPalindrome(string s) {
            int longest = 0, start = 0;
            int cent, i, tmp, flag;
            string anw;
            for(cent = 0; cent < s.length(); cent++) {
                tmp = 1;
                flag = 0;
                for(i = 1; i < s.length() - cent && i <= cent; i++) {
                    if(s[cent - i] == s[cent + i]) {
                        tmp+=2;
                        flag = cent - i;
                    } else break;
                }
                if(tmp > longest) {
                    longest = tmp;
                    start = flag;
                }
                
                if( cent+1 < s.length() && s[cent] == s[cent+1]) {
                    tmp = 0;
                    flag = 0;
                    for(i = 0; i < s.length() - cent - 1 && i <= cent; i++) {
                        if(s[cent - i] == s[cent + 1 + i]) {
                            tmp += 2;
                            flag = cent - i;
                        } else break;
                    }
                }
                if(tmp > longest) {
                    longest = tmp;
                    start = flag;
                }
            }
            anw.assign(s, start, longest);
            return anw;
        }
    };
    
  2. 定义p(i, j) = true if s(i, j)为回文,所以根据回文特点有:

    p(i, i) = true;
    p(i, i + 1) = (s[i] == s[i+1]);
    p(i, j) = p(i+1, j-1) 且 (s[i] == s[j]) 否则 p(i, j) = false;
    

    所以,使用dp[len+1][len+1]来记录p[i][j]的值。并且使用start和max_dist来保存当前得到的回文的起始值和当前回文末尾起始值的距离。dist为字符串起始与末尾的距离。

    class Solution {
    public:
        string longestPalindrome(string s) {
            int len = s.length(), i, dist, start = 0, max_dist = 0;
            bool dp[len+1][len+1];// dp[len][len] will lead to error when s is NULL, so use dp[len+1][len+1]
            
            for(i = 0; i < len; i++) {
                dp[i][i] = true;
            }
            
            for(dist = 1; dist < len; dist++) {
                for(i = 0; i + dist < len; i++) {
                    if(s[i] == s[i+dist]) {
                        if(dist == 1) {
                            dp[i][i+dist] = true;
                        } else {
                            dp[i][i+dist] = dp[i+1][i+dist-1];                        
                        }
    
                    } else {
                        dp[i][i+dist] = false;
                    }
                    
                    if(dp[i][i+dist] == true) {
                        start = i;
                        max_dist = dist;
                    }
                }
            }
            
            return s.substr(start, max_dist+1);
        }
    };
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值