LeetCode5 最长回文串

暴力求解法

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


#ifndef _SOLUTION_H
#define _SOLUTION_H

/**思路: 
从回文串的对称点开始,依次向左向右比较,不相同的时候停止遍历,直到找出最大的长度的回文子串。
*    (1)回文子串长度为奇数:对称点只有一个字符
*    (2)回文子串长度为偶数:对称点有两个字符
时间复杂度为O(n^2):对称点的数量为O(n),每次查找的时间也为O(n),所有总时间复杂度为O(n^2) */
class Solution {
public:
    string longestPalindrome(string s) {
        //字符串的长度
        int len = s.size();
        if (len == 0) return s;
        //保留最长回文串
        string resultStr = "";
        //回文子串长度为奇数,:对称点只有一个字符的情况
        for (int i=0; i// i 为对称点
            int left = i;//左
            int right = i;//右
            //向左向右遍历,直到发现不相同的时候停止
            while (left > 0 && right < len - 1 && s[left - 1] == s[right + 1]){
                --left;
                ++right;
            }
            //比较,更新最长回文串
            if (right - left + 1 > resultStr.size()){
                resultStr = s.substr(left, right - left + 1);
            }
        }

        //回文子串长度为偶数:对称点有两个字符
        for (int i = 0; i < len - 1; ++i){
            if (s[i] == s[i+1]){//两个对称点相同,才有继续遍历的意义
                int left = i;
                int right = i+1;
                //向左向右遍历,直到发现不相同的时候停止
                while (left > 0 && right < len - 1 && s[left - 1] == s[right + 1]){
                    --left;
                    ++right;
                }
                //比较,更新最长回文串
                if (right - left + 1 > resultStr.size()){
                    resultStr = s.substr(left, right - left + 1);
                }
            }
        }
        return resultStr;
    }
}; 

#endif

方法2 DP(Dynamic Programming)方法

我们维护一个二维数组dp,其中dp[i][j]表示字符串区间[i,j]是否为回文串,当i==j时,只有一个字符,肯定是回文串,如果i=j+1,说明是相邻字符串,此时需要判断s[j]是否等于s[j],如果i=j+1,说明是相邻字符,此时需要判断s[i]是否等于s[j].如果i和j不相邻,需要除了判断s[i]s[j]相等之外dp[j+1][i-1]若为真,就是回文串。
可以写出如下递推式子:
dp[i,j] = 1
if i == j
if j = i + 1& s[i] == s[j]
if j-i>=2&s[i]==s[j]&dp[j+1][i-1]==1
不断更新索引,找出最长len.

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


#ifndef _SOLUTION_H
#define _SOLUTION_H

// DP
class Solution {
public:
    string longestPalindrome(string s) {

        int dp[s.size()][s.size()] = {0}, left = 0, right = 0, len = 0;
        for (int i = 0; i < s.size(); ++i) {
            for (int j = 0; j < i; ++j) {
                dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j + 1][i - 1]));
                if (dp[j][i] && len < i - j + 1) {
                    len = i - j + 1;
                    left = j;
                    right = i;
                }
            }
            dp[i][i] = 1;
        }
        return s.substr(left, right - left + 1);
    }
};
#endif 

Manacher’s Algorithm

时间复杂度为O(n)

.

你可能感兴趣的:(算法设计)