leetCode刷题之最长回文子串

    乍一见这个题目,我的心是畏惧的。然后又生出必须要战胜的决心。至于为什么感情如此丰富呢?主要还是因为这道题曾经成为我的一道坎坷。大一上学期学习C语言的时候,刚开始特别迷恋编程,天天刷题到图书馆关门。那时候真是一道题做一天正常的很(夸张夸张,不过半天确实有)。不过大一呀,正是玩乐的好时机,于是乎心慢慢松了。这道题卡了第55题,对于那时刚刚接触编程才2个月的我当真麻烦的很,加上C语言指针什么的,更是头脑发热。于是在半天思索还不见方案的前提下,我选择了跳过这道题,继续刷其他题。看起来情有可原,实际上却是畏惧!哎哎哎。。。不说了。总之今天看到这道题,第一感觉就是征服,不仅要解决,还要用各种方法解决!

    不说了,晾题:

    

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 长度最长为1000。

示例:

输入: "babad"

输出: "bab"

注意: "aba"也是有效答案

    先说看到这道题目的思路吧,我的反应如下:

    1、将字符串s进行遍历。

    2、判断当前的节点是否符合回文串条件,奇偶两种情况。

    3、符合回文串的像两端扩展,并且添加到容器中。

    4、获的list容器,存储着所有的回文串,和第一个字符(如果没有2个或2个以上字符组成的回文串,就以第一个字符为最长回文串计算)。

    5、对list进行排序,选取最长的回文串作为结果返回。

一下就是我首次的代码:

    public static String longestPalindrome(String s) {
        //存储不同长度的回文串
        List sbList = new ArrayList();
        boolean isTwoCycle = false;
        boolean isThreeCycle = false;
        //默认将第一个字符传入list,作为默认最长回文串
        sbList.add(new StringBuffer(String.valueOf(s.charAt(0))));
        for(int i = 1; i < s.length() ;i++){
            //判断当前字符是否构成回文串,是奇数还是偶数
            if(s.charAt(i) == s.charAt(i-1)){
                isTwoCycle = true;
            }
            if(i >= 2 && (s.charAt(i)==s.charAt(i-2))){
                isThreeCycle = true;
            }

            int cursor = 1;
            //如果是以两个重复字为回文串
            if(isTwoCycle){
                //字符串下标不能小于0,同时不能超过字符串长度
                while(i-cursor>=0 && i+cursor-1=0 && i+cursor-1() {
            @Override
            public int compare(StringBuffer sb1, StringBuffer sb2) {
                return -(sb1.length() - sb2.length());
            }
        });

        return sbList.get(0).toString();
    }

兴冲冲地写完,然后提交居然一次性成功,心里窃喜还没有停下,就突然蹦出一个134ms。纳尼?134ms,仔细一看最快的,我去!7ms,神啊!有木有?心里的窃喜马上止住,赶忙打开7ms的代码,那个简洁,那个巧妙,那个精美......

    鄙人花了一些时间仔细看了一下代码,然后自己书写了一遍,如下:

/**
 * 可以看出,整个算法的核心主要有三点:
 *  1、将str字符串转换成数组进行处理
 *  2、将偶回文处理,使之变成奇回文的处理方式(重)
 *  3、使用int[]数组,合理地记录字符数组的下标,并以此来比较回文串长度大小
 * Created by v_shampoowang on 2018/4/11.
 */
public class PalindromeString {
    public static void main(String[] args){
        System.out.println(new PalindromeString().
                longestPalindrome("aba"));
    }

    //求最长回文子串
    public String longestPalindrome(String str){
        if(str.length()<=1) return  str;
        char[] characters = str.toCharArray();
        //用于存放str中最长回文子串所对应的下标
        int[] range = {0,1};
        for(int i = 0;i=0&&c[low-1]==c[high+1]){
            low--;
            high++;
        }
        if(high-low+1>range[1]-range[0]){
            range[0] = low;
            range[1] = high + 1;
        }
        return cursor;
    }
}

    看完别人的代码,此处不由得开始深思,我用了134ms!别人只用了7ms,近20倍的差距!仔细深析一下原因:

最大的原因肯定是自己考虑的点不对,未能能将多种处理方法归并到一起,是积累不够,也是敏感度地欠缺。

第二,变量使用率上不够,很多变量的庞大,但是使用次数不多。

第三,产生了很多不必要的东西,比如list存储了很多没有必要的数据。

第四,尽量使用原生的数组,能够将消耗变得最小,同时也能最大地提升效率。以前学C的时候就是使用数组,现在工作了一段时间,对容器的依赖加重了好多。

    总结:虽然自己现在的算法还不如很多大一学生,并且很多情况下对于我这个业务工程师来说,算法的精妙度体现不出来。但是算法的编写又何尝不是提升思维能力,提升学习兴趣的过程。或许我现在只是一个业务工程师,但是说不定,几年之后,我就像算法转型了呢?就算不是,加深对数据结构和算法的理解,也是身为一个程序员锁必不可少的过程!

    在此互勉,共同进步。欢迎大家批评指正。

    

你可能感兴趣的:(leetcode,刷题,算法,java语言,成长之路,leetcode,算法,java成长之路)