my raw answers for leetcode - 5. Longest Palindromic Substring

12 篇文章 0 订阅
9 篇文章 0 订阅

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"

 

class Solution {
public:
    
    string stringReversal(string s){
        string sr;
        for(int i = s.length()-1,j=0; i >=0,j<s.length(); i--,j++)
        {
            sr.insert(j, {s.at(i)});
        }
        return sr;
    }
    
    string longestPalindrome(string s) 
    {
        string the_string;
        int max_palindromic_length = 0;
        for(int i = 0; i < s.length(); i++)
        {
            for(int j = i; j<s.length(); j++)
            {
                string this_str;
                for(int x = i,y=0; x<=j;x++,y++)
                {
                    this_str.insert(y,{s.at(x)});    
                }
                string sr = stringReversal(this_str);
                if(sr == this_str){
                    if(j-i>=max_palindromic_length){
                        max_palindromic_length = j-i;
                        the_string = this_str;
                    }
                }
            }
        }
        return the_string;
    }
};

 

comment:

The big-oh of Time-Complexity is too large that can't hit the calculating time requirement of leetcode when they input a very long string...

 

 

Solution 2: Longest common substring

 

code:

    string longestPalindrome(string s) 
    {
        if(s.length()==1) return s;
        string rev = s;
        std::reverse(rev.begin(), rev.end());
        if(rev==s) return s;
        string result;
        int len = 0;
        for(int i = 0; i<s.length(); i++)
        {
            string sub_string;
            for(int j=i; j<s.length();j++)
            {
                sub_string = sub_string + s[j];
                if(len>=sub_string.length()){
                    continue;
                }else if(rev.find(sub_string)!=-1){
                    string check = sub_string;
                    std::reverse(check.begin(), check.end());
                    if(sub_string == check){
                        len = sub_string.length();
                        result =sub_string;
                    }
                }else{
                    break;
                }
            }
        }
        
        
        return result;
    }

 

comment:

It's still out of time when input is too long. 

 

Solution2: Dynamic Programming

code:

    string longestPalindrome(string s) 
    {
        int len = s.size();

        if(len==0||len==1){

            return s;}
        vector<vector<int>> dp(len, vector<int>(len));
        int start = 0;
        int max = 1;
        for(int i = 0; i < len; i++)
        {
            dp[i][i] = 1;//if dp[x][y] is equal to 1, it's a palindromic string
            if(i<len-1&&s[i]==s[i+1]) //a string of two consecutive identical letters is a palindromic string
            {
                dp[i][i+1] = 1;
                start = i;
                max = 2;
            }
        }
        for (int l = 3; l<=len; l++)
        {
            for(int i = 0; i+l-1<len; i++)
            {
                int j = i+l-1;
                if(s[i]==s[j]&&dp[i+1][j-1]==1) //if a string xyz is already a palindromic string, and let's say axyzb, if a ==b, axyzb is                                                                       //palindromic string too
                {
                    dp[i][j] = 1;                          //now,let axyzb be palindromic string
                    start = i;
                    max = l;
                }
            }
        }
        return s.substr(start, max);
    }

 

comment:

256 ms186.5 MBCpp

 

I think my notes are clear enuf...

 

Solution4: Expand Around Center

code:

class Solution {
public:
    string longestPalindrome(string s) 
    {
        int len = s.size();
        if(len==0||len==1)
        {
            return s;
        }
        int mlen = 0;
        int start = 0;
        int end = 0;
        for(int i = 0; i < len; i ++)
        {
            int len1 = sizeOfPalindromic(s, i, i);
            int len2 = sizeOfPalindromic(s, i, i+1);
            mlen=max(max(len1,len2),mlen);
            if(mlen>end-start+1)
            {
                start = i-(mlen-1)/2;
                end = i+mlen/2;
            }
            
        }
        return s.substr(start, mlen);         //from start, and mlen length of string
    }
private:
    int sizeOfPalindromic(string s, int left, int right)
    {
        int L=left;
        int R=right;
        while(L>=0&&R<s.size()&&s[L]==s[R])
        {
            L--;
            R++;
        }
        return R-L-1;      //this return the value of length of a palindromic string,

                                  //it's kinda confusing, cuz the while loop expanded the length of it

                                  //in a fact, R-L-1 is the real palindromic string
    }
};

comment:

44 ms104.1 MBCpp

 

 

Solution5: Manacher

code:

    string longestPalindrome(string s) 
    {
        if(s.length()<1){
            return "";
        }
        
        string vs;
        for (int i = 0; i <s.length(); i ++){
            vs += "#";
            vs += s[i];
        }
        vs += "#";                                 //we let string be #a#b#c#b#a#, to let the virtual string(vs) be an odd number of string                                                                    // later we just divides it by 2 to get the original position
        
        int len = vs.length();
        int pos = 0;                               //the current pos of currentMaxRight
        int currentMaxRight = 0;          //as the name represents, if current palindromic string's right of loop beyond it, we update it.
        int maxPos = 0;                       //to store the max radius of a pos
        int maxRL = 0;                        // to strore the max radius
        int * RL = new int[len];             //to store the current radius
        for(int i = 0; i <len; i ++)
        {

            //we initialize the radius in one of 2 cases
            if(i<currentMaxRight){   //case one: the i is on the left side of currentMaxRight.

                                                  //there is either j(j is a symmetric point with pos as axis i)'s left reaches the currentMaxLeft                                                            //or right reaches currentMaxRight

                                                  //and we pick the limited situation, hence we use min()
                RL[i] = min(RL[2*pos-i],currentMaxRight-i);
            }else   //case two: i is on the right side of currentMaxRight, or just on currentMaxRight
            {
                RL[i] = 1;  //included the i himself, hence later we gotta use RL[i]-1 to caculate the distance
            }
            

            //now we start to expand from current center
            while((i-RL[i]>=0)&&(i+RL[i]<len)&&(vs[i+RL[i]]==vs[i-RL[i]]))  //of course left or right can't beyond border
            {
                RL[i] +=1;
            }
            
            //if i+RL[i] is greater than currentMaxRight, update it to i+RL[i] 
            if(i+RL[i]-1>currentMaxRight)
            {
                currentMaxRight = i+RL[i]-1;
                pos = i;
            }
            //if RL[i]>currentMaxRight-pos
            if(RL[i]>=maxRL)
            {
                maxPos = i;
                maxRL= RL[i];
            }
        }
        return s.substr((maxPos-(maxRL-1))/2, maxRL - 1);         //cuz of it's virtual string, hence divided by 2                                                                                                                                       //and we said distance is RL-1
    }

 

comment:

8 ms9.9 MBCpp

The main idea of this algorithm is to make use of the attribute of symmetry of a palindromic string to avoid repetitive operation, while does "Expand Around Center" at the same time.

I think my notes are clear enuf...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值