Problem5

题目

原题描述:

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

Output: "bab"

Note: "aba" is also a valid answer.
 
Example:
Input: "cbbd"

Output: "bb"
题目提炼

给定一个字符串,求出其最长的回环子串。

分析

首先解释一下回环串的定义,回环串就是形如:aba、aabbaa这种,正序和逆序都一样的字符串。由此可知,回环串一定是对称的。并且因为要求最长回环子串,所以这里必然有标记每一次结果的变量tmp与标记当前最长子串的变量result。这里给定了一个子串,让我们求出其最长的回环子串,可以从两个角度考虑,
1.一个是先找回环子串的两个端点,然后从两端逼近,这样的好处就是不需要区分子串长度为奇数还是偶数,但是缺点在于需要写三层循环。
算法如下:

1.令字符串为s,选取左端点left=0,右端点right=string.length;
2.比较两个端点的字符是s[left]与s[right]是否相同,如果不相同则right--然后跳到第4步;相同则执
行第3步。
3.令i=left+1;j=ringht-1;比较s[i]与s[j]是否相同,不相同则跳到第5步如果相同则i++,j--然后继续
比较直到s[i]与s[j]不同或者i=j;当i=j时,result=max(result,tmp)
4.ringht--,返回第2步直到right=left;
5.left++,返回第2步,直到s.length-left小于当前最长回环子串长度。

代码如下:

public String solustion(String s){

        char[] a=s.toCharArray();

        int end=0;

        int start=0;

        for(int i=0;i<s.length();i++){

            char c=a[i];

            for(int n=s.length()-1;n>i;n--){

                if(c==a[n]) {

                    char c2=c;

                    boolean flag=false;

                    for (int j = n; ; ) {

                        if (c2 == a[j]) {

                            j--;

                            if (j >i) {

                                c2 = a[n - j+i];

                            } else {

                                if((n-i)>(end-start))

                                {

                                    end=n;

                                    start=i;

                                    flag=true;

                                }

                                break;

                            }

                        } else {

                            break;

                        }

                    }

                    if (flag) {

                        break;

                    }

                }

            }

            if ((end-start)>s.length()-i)

            {

                break;

            }

        }

        return s.substring(start,end+1);

    }

2.是从回环子串的对称中心开始向两端逼近,这个的好处就是减少了循环次数,但是要判断长度为奇数还是偶数。

 public String solution2(String s){

        int center=0;

        int len=0;

        char[] a=s.toCharArray();

        for(int i=0;i<a.length;i++)

        {

            int len1=getlen(a,i,i);

            int len2=getlen(a,i,i+1);

            int len3=Math.max(len1,len2);



            if(len3>len){

                len=len3;

                center=i;

            }

            if(len>(a.length-i)*2) {
                break;
            }
        }
        return s.substring(center-(len-1)/2,center+len/2+1);
    }

    private int getlen(char[] s, int left, int right) {
        int l = left,  r= right;
        while (l >= 0 && r < s.length && s[l] == s[r]) {
            l--;
            r++;
        }
        return r - l - 1;
    }

特记

寻找最长回环字串有一个很出名的算法,叫做(马拉车)算法。他能将时间复杂度降低到O(n),但是因为这个算法不是一般性的,所以在面试笔试中不会考到,可以作为拓展了解。这个算法可以参考博客(www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html),讲的十分详细。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。 2、用C语言实现函数void ...
    希崽家的小哲阅读 6,377评论 0 12
  • 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不...
    曲终人散Li阅读 3,394评论 0 19
  • 标签(空格分隔): 算法 C++ 笔试 第三题:描述小王最近在开发一种新的游戏引擎,但是最近遇到了性能瓶颈。于是他...
    认真学计算机阅读 1,955评论 0 8
  • 说明: 本文中出现的所有算法题皆来自牛客网-剑指Offer在线编程题,在此只是作为转载和记录,用于本人学习使用,不...
    秋意思寒阅读 1,173评论 1 1
  • 记得第一次见到老曲的时候,头发长到耳下,身穿白大褂,脚踏拖鞋,外加胡子拉碴,当真以为是哪个四十多的老师。 婚礼前夕...
    璞书茗阅读 327评论 4 2