LeetCode_Longest Palindromic Substring

题目描述:给定一个字符串,找出字符串中最长的回文串。
eg:

  • input:abbc

  • output:bb

  • input:babad

  • output:bab or aba

我的代码(暴力法)

string longestPalindrome(string s) 
    {
        map<int,string> vec;
        if(s.size()==1) return s;
        if(s.size()==2)
            if(s[0]==s[1])
                return s;
        int length=s.size();
        vec.insert({1,s.substr(0,1)});
        while(length>1)          //控制length长度
        {
            int i=0;
            int mid=length/2;
            int j=length-1;
            while(i<=s.size()-length)  //在length长度内迭代求解
            {
              int num=0;
              int i_cp=i;
              int j_cp=j;
              int mid_cp=mid;
              while(i_cp<mid_cp)
              {
                  if(s[i_cp]==s[j_cp])
                      num++;
                  i_cp++;
                  j_cp--;
              }
              if(num==length/2)
              {
                  vec.insert({length,s.substr(i,length)});
                  return s.substr(i,length);
              }
              else
                  i++,mid++,j++;
            }
            length--;
        }
        return vec[1];
    }

复杂度分析:三个while循环的嵌套,所以O(n^3)级别
缺陷:复杂度高,虽然没什么问题,提交时系统给的输入是"klvxwqyzugrdoaccdafdfrvxiowkcuedfhoixzipxrkzbvpusslsgfjocvidnpsnkqdfnnzzawzsslwnvvjyoignsfbxkgrokzyusxikxumrxlzzrnbtrixxfioormoyyejashrowjqqzifacecvoruwkuessttlexvdptuvodoavsjaepvrfvbdhumtuvxufzzyowiswokioyjtzzmevttheeyjqcldllxvjraeyflthntsmipaoyjixygbtbvbnnrmlwwkeikhnnmlfspjgmcxwbjyhomfjdcnogqjviggklplpznfwjydkxzjkoskvqvnxfzdrsmooyciwulvtlmvnjbbmffureoilszlonibbcwfsjzguxqrjwypwrskhrttvnqoqisdfuifqnabzbvyzgbxfvmcomneykfmycevnrcsyqclamfxskmsxreptpxqxqidvjbuduktnwwoztvkuebfdigmjqfuolqzvjincchlmbrxpqgguwuyhrdtwqkdlqidlxzqktgzktihvlwsbysjeykiwokyqaskjjngovbagspyspeghutyoeahhgynzsyaszlirmlekpboywqdliumihwnsnwjc"(…),这样运行的时间太长,提交错误,需要别的算法。

Solution:
expendAroundcenter
算法思想:每个回文串都是关于某个元素对称的,所以我们可以从对称中心向左右拓展,偶数的对称中心是相邻且相等的两项

代码:

string longestPalindrome(string s) 
    {
        int start=0;
        int end=0;
        for(int i=0;i<s.size();i++)
        {
            int len1=expendAroundcenter(s,i,i);
            int len2=expendAroundcenter(s,i,i+1);
            int len=max(len1,len2);
            if(len>end-start+1)
            {
                start=i-(len-1)/2;
                end=i+(len/2);
            }
        }
        return s.substr(start,end-start+1);
    }
    int expendAroundcenter(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;
    }

复杂度:O(n^2)

Dynamic Programming:看作动态规划问题,我们维护一个二维数组dp[i][j],若dp[i][j]=1,则说明下标从i到j的子串为回文串,若dp[i][j]为回文串,那么dp[i+1][j-1]也必定为回文串

代码:

string longestPalindrome(string s) 
    {
        if(s.size()==0)
            return "";
        int start=0;
        int length=1;
        int dp[s.size()][s.size()]={0};
        for(int right=0;right<s.size();right++)
        {
            dp[right][right]=1;
            for(int left=0;left<right;left++)
            {
                if(s[left]==s[right]&&(right-left<2||dp[left+1][right-1]==1))
                {
                    dp[left][right]=1;
                }
                else
                    dp[left][right]=0;       //不为1的,设为0,若不设置会乱码
                if(dp[left][right]==1&&length<right-left+1)
                {
                    start=left;
                    length=right-left+1;
                }
            }
        }
        return s.substr(start,length);
    }

复杂度:O(n^2)

总结:

  • 暴力算法虽然简单,但复杂度高,有时不适用(超过n^2时)
  • 找出回文串的特点(对称)
  • 动态规划时,要保证可变数组的长度为正值,因此先要判断空串的情况
  • 因为没有考虑到数组元素不为1时的情况,因此在debug时花费了不少时间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值