最长回文数

1:题目描述

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

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

来源:力扣(LeetCode)

2:题目分析

  回文数是一种左右对称的字符串,如果从题目的背景一个大字符串出售,很容易使用暴力法,直接从1开始拓展成length-1长度,然后分别进行回文数判断,这种方法是最直接,最好想的,当然也是最消耗时间的。如果换个角度好好分析,回文数的特点我门可以通过找到对称中心的方式来进行找到回文数。

3:代码示例

3.1:暴力法

class Solution {
    public String longestPalindrome(String s) {
        //char[] c = new char[s.length()];
        //s.getChars(0,s.length(),c,0);
        int startIndex = 0;
        int charAmount = 0;
        int startIndexTemp = 0;
        int charAmountTemp = 0;
        for(int i=1;i<=s.length();i++){//从2开始,直到字符串长度的大小,极端情况可能一个最长的回文数就为本身
            char[] chars = new char[i];
            for(int j=0;j<s.length()-i+1;j++){//将字符串放在chars中,依次移动范围
                s.getChars(j,j+i,chars,0);
                //寻找之前保存原来的结果,
               for(int k =0;k<=chars.length/2;k++){
                    if(chars[k]==chars[chars.length-1-k]){
//                        startIndex = j;
//                        charAmount = i;
                        if(k==(chars.length/2)){
                            startIndex = j;
                            charAmount = i;
                        }
                        continue;
                    }
                    break;
                }
                if(charAmount==i){//则意味着已经找到了回文数,
                    break;//只要该长度找到一个回文数了,则直接break
                }
                else{//此处没有找到回文数,则向后移动位置,在继续寻找
                    continue;
                }
            }
        }

        return s.substring(startIndex,startIndex+charAmount);
    }
}

通过三次循环来暴力解决这个问题。第一层循环为控制回文字符串长度,以该长度来在目标字符串上进行判断,第二层循环了控制该固定长度的字符串在目标字符串上移动,第三层才为判断该字符串是不是回文字符串的。至此三层循环O(n^3)的时间复杂度,当然过不了leetcode时间要求。

3.2:中心展开法

由于所有回文字符串都是中心对称的,所以可以从中心点来作为出发点判断是不是回文字符串,则这种解决方式的O(n^2),因为第一次循环为遍历中心点,在n个字符串中,中心点有n+n-1个,可以是本字符为中心点也可以是两个字符中间为中心点!,算法思路为,先找到对称中心点,然后再以该中心分别向两边拓展来判断是不是回文数即可。

    //回文数可以是偶数长度,也可以是奇数长度
    //即可以是在一个字符处向右向左拓展,判断
    //或者是,从两个字符中间空位置开始向左向右判断
    //该方法来控制回文数的中心位置
    public String longestPalindrome(String s){
        String result = new String("");
        String tempString = null;
        for(int start = 0;start<s.length();start++) {
            String s1 = appendLength(s, start, start);//中心点再字符处
            String s2 = appendLength(s, start, start + 1);//中心点在两个字符之间
            tempString = s1.length()>=s2.length()?s1:s2;
            if(tempString.length()>result.length()){
                result = tempString;//若此次的结果长度大于上次的则保存此次!
            }
        }
        return result;
    }

    //以输入字符串和指定的起始位置向两边扩展来寻找回文字符串!
    public String appendLength(String s,int left,int right){
        int length=0;
        int l = left;
        int r = right;
        while(l>=0&&r<s.length()&&s.charAt(l)==s.charAt(r)){
            length = r-l+1;
            l--;
            r++;
        }
        return s.substring(l+1,r);//截取上面得到的回文字符串
    }

 

posted @ 2020-03-03 20:15  大朱123  阅读(564)  评论(0编辑  收藏  举报