zoukankan      html  css  js  c++  java
  • LeetCode5: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.

    解题思路:

    主要有三种:

    第一种:Manacher算法,也是最快的,时间复杂度为O(n)

    第二种:DP算法,时间复杂度为O(n*n)

    第三种:中心法,时间复杂度为O(n*n)

    实现代码:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    /**
    
    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.
    */
    
    class Solution {
    public:
        //Manacher算法(O(n))
        string longestPalindrome(string s) {
            string p;
            if(s.empty())
                return p;
            int id = 0;
            int mx = 0;
            //以下对要操作的副本str进行格式化,使得其为奇数 
            string str("^");       
            for(int i = 0; i < s.size(); i++)
            {
                str += "#";
                str += s[i];
            }
            str += "#$";
            vector<int> r(str.size(), 0);
            
            for(int i = 1; i < str.size()-1; i++)
            {
                if(mx > i)
                    r[i] = min(r[2*id - i], mx - i);
                else
                    r[i] = 1;
                while(str[i+r[i]] == str[i-r[i]])//为了防止越界,str头尾插入了'^'和'$'字符 
                    r[i]++;
                if(r[i] + i > mx)
                {
                    mx = r[i] + i;
                    id = i;
                }
            }
            
            int maxlen = 0;
            int maxid = 0;
            for(int i = 1; i < str.size()-1; i++)
            {
                if(r[i] > maxlen)
                {
                    maxlen = r[i];
                    maxid = i;
                }            
            }
            //(maxid-1)/2为原字符串中最长回文字串中心字符位置
            //(maxlen-1)/2为原字符串中最长回文子串半径
            //maxlen-1为原字符串中最长回文字串长度 
            return s.substr((maxid-1)/2 - (maxlen-1)/2, maxlen-1);
       
        }
        
        //DP O(n*n)
        string longestPalindrome2(string s) {
            string p;
            if(s.empty())
                return p;
            int len = s.size();
            vector<vector<bool>> dp(len, vector<bool>(len, false));//dp[i][j]表示i~j的字串是否为回文串 
            int maxstart = 0;
            int maxlen = 1;
            for(int i = 0; i < len-1; i++)
            {
                dp[i][i] = true;
                if(s[i] == s[i+1])
                {
                    dp[i][i+1] = true;
                    maxstart = i;
                    maxlen = 2; 
                }
            }
            
            for(int l = 3; l <= len; l++)
            {
                for(int i = 0; i < len-l+1; i++)
                {
                    int j = i+l-1;
                    if(s[i] == s[j] && dp[i+1][j-1])
                    {
                        dp[i][j] = true;
                        maxstart = i;
                        maxlen = l;
                    }
    
                }
            }
            return s.substr(maxstart, maxlen);
    
        }
    
        
        //中心法,以每一个字符作为回文串中心,向两边扩展 
        string longestPalindrome3(string s) {
            string p;
            if(s.empty())
                return p;
            int len = s.size();
            int maxstart = 0;
            int maxlen = 0;
            for(int i = 0; i < len; i++)
            {
                int l = i-1;
                int r = i+1;
                int tmpmax = 1;//已i为中心的回文串:奇数 
                while(l >= 0 && r < len && s[l--] == s[r++])
                    tmpmax++;
                if(maxlen < tmpmax*2 -1)
                {
                    maxlen = tmpmax*2 -1;
                    maxstart = l+1;
                }
                
                int l2 = i;
                int r2 = i+1;
                int tmpmax2 = 0;//已i和i+1为中心的回文串,偶数时 
                while(l2 >= 0 && r2 < len && s[l2--] == s[r2++])
                    tmpmax2++;
                
                if(maxlen < tmpmax2*2)
                {
                    maxlen = tmpmax2*2;
                    maxstart = l2+1;
                } 
     
            }
    
            return s.substr(maxstart, maxlen);
       
        } 
           
    };
    
    
    int main(void)
    {
        string s("abbacdd");
        Solution solution;
        string p = solution.longestPalindrome3(s);
        cout<<p<<endl;
        return 0;
    }
  • 相关阅读:
    CSRF 攻击
    PHP中HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用
    PHP PDO函数库详解
    STK基础
    opnet统计结果的采集模式——capture mode
    一个博客园代码高亮的方案
    博客园TinyMCE编辑器中插入的代码块使用HTML编辑器再编辑
    local statistics和global statistics的区别
    opnet的函数中FIN、FRET和FOUT
    福昕阅读器默认打开pdf文件视图大小
  • 原文地址:https://www.cnblogs.com/mickole/p/3702747.html
Copyright © 2011-2022 走看看