求最长回文子串

原题如下:

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

时间复杂度为n平方.总体思路如下:

首先,外层遍历从1开始寻找一个中心点,再一一比较中心点两边是否相等,比如说:

babad

    一开始的中心点是a,下标i=1,我们比较一下s[i-1]和s[i+1]是否相等,如果相等,左边继续-,右边接着+,同时lenght同步计数.用maxlenght记录最大值.用max记录最大回文子串的起始位置.

    同时考虑特殊情况,比如说:

baab 当i=1时,以a为中心,我们需要希望是s[i]和s[i+1]比较然后是s[i-1]和s[i+2]比较.这样子,当s[i]==s[i+1]时就有两种扩展方式,要两种都写出来.

    代码如下:

var longestPalindrome = function(s) {
     var l=s.length;
            var lenght=1;
            var max=0;
            var maxlenght=0;
            var flag=1;
            var j,k;
            var flag1=1;
            if(s[0]==s[1]){
                maxlenght=2;
                max=0;
            }
            for(var i=1;i<l;i++){
                flag=1;
                flag1=1;
                for(j=i,k=i;j>=1&&k<l-1&&flag;) {
                    if (s[i] == s[i + 1] && flag1 === 1) {
                        k++;
                        lenght++;
                        flag1 = 0;
                        if (lenght > maxlenght) {
                            maxlenght = lenght;
                            max = i;
                        }
                    }
                    j--;
                    k++;
                   //alert("i---"+i+"j---"+j+"k---"+k);
                    //alert(s[j]===s[k]);
                    if (s[j] == s[k]) {
                        lenght = lenght + 2;
                    }
                    else {
                        flag = 0;
                        if (lenght > maxlenght) {
                            maxlenght = lenght;
                            max = j + 1;
                        }
                        lenght = 1;
                    }
                    if ((j === 0 || k == l - 1) && s[j] === s[k]) {
                        if (lenght > maxlenght) {
                            maxlenght = lenght;
                            max = j;
                        }
                        lenght = 1;
                    }
                }
                    // alert("长度是:"+lenght+"起点"+max);
                    // alert("i=="+i);
                flag=1;
                for(j=i,k=i;j>=1&&k<l-1&&flag;){
                        j--;
                        k++;
                        //alert("j=="+j+"k=="+k);
                        /*alert("i---"+i+"j---"+j+"k---"+k);
                         alert(s[j]===s[k]);*/
                        if(s[j]==s[k]){
                            lenght=lenght+2;

                        }
                        else{
                            flag=0;
                            if(lenght>maxlenght){
                                maxlenght=lenght;
                                max=j+1;
                            }
                            lenght=1;
                        }
                        if((j==0||k==l-1)&&s[j]==s[k]){
                            if(lenght>maxlenght){
                                maxlenght=lenght;
                                max=j;
                            }
                            lenght=1;
                        }
                    }


            }
            if(lenght>maxlenght){
                maxlenght=lenght;
                max=j;
            }
            if(l===1){
                //alert("长度是1");
                return s;
            }
            if(l===2&&s[0]===s[1]){
                //alert("长度是2");
                return s;

            }else if(s[0]!==s[1]&&l===2){
                //alert("长度是2");
                return s[0];
            }

            var r=s.substr(max,maxlenght);
           return r;
};

可是这样子好麻烦,能不能将s[i]==s[i+1]的时候扩展方式合并起来呢,答案当然是可以的,通过找资料发现,更简便的做法是:

当遇到相同的字符时,我们记录相同字符的起始位置和结束位置,以起始位置向左边扩展,以终点位置向右边扩展,举个例子:

sooos:

当i==1时,我们发现s[i]==s[i+],这时候我们记录下起点start是i,然后有3个o,所以相同字母字符串的终点end是3,这时候,咱们比较s[start-1]和终点s[end+];如果相同,就记录长度.这样就将两种扩展方式结合起来了.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值