这道题要求的是给你一个string, 如“adcdabcdcba",要求返回长度最大的回文子字符串。这里有两个条件,一是子字符串,而是回文。用纯暴力搜索的话,需要用到O(n^3)的时间,必然超时。就算经过细节上的优化,它也有一个很长的test case不一定能过得去(说不一定是因为有时能过有时不能过),先贴上这个O(n^3)的代码,其实可以不用仔细看,面试用这种方法可不能过,所以大概了解一下就好,它只是对之后如何产生O(n^2)的代码做个铺垫,代码如下:

 public class Solution {
public String longestPalindrome(String s) {
int length = s.length();
char[] charArray = new char[length];
for (int i = 0; i < s.length(); i++) {
charArray[i] = s.charAt(i);
}
int head = 0, tail = length - 1;
int distance = 0;
for (int i = 0; i < length; i++) {
for (int j = length - 1; j > i; j--) {
if (isPalindrome(charArray,i,j)) {
if (j - i + 1 > distance) {
head = i;
tail = j;
distance = j - i + 1;
break;
}
}
}
if (distance >= length - i) break;
}
StringBuilder sb = new StringBuilder();
for (int i = head; i <= tail; i++) {
sb.append(charArray[i]);
}
return sb.toString();
} private boolean isPalindrome(char[] charArray,int head,int tail) {
while (head < tail) {
if (charArray[head++]!= charArray[tail--]) return false;
}
return true;
}
}

  我所采取的优化的方式是第二重循环是由后往前,碰到回文就跳出内循环(因为该回文一定是该循环里最长的循环),然后内循环结束后,如果最大的distance >= s.length() - i,说明外循环就没有必要继续再走下去(i继续增加,s.length() - i只会变小),可以直接break掉。这样子,在“运气”成份下,上述代码就存在了AC的情况。

  如果O(n^3)的方法不能够解决,那有没有O(n^2)的方法呢?经过思考我们可以发现,上述代码之所以是O(n^3),是因为辅助函数里还有一重循环O(n)。既然判断回文花费的时间一定是O(n),那么在主函数里,能不能只用一重循环呢?可以的。上面的代码判断回文是从两端往中间走,就是因为要确定两端才需要O(n^2)的时间,加上判断回文,那就是O(n^3)了。但如果我们是从中间往两端走呢?中间往两端走,判断回文虽然也需要O(n),但是确定中点,却只需要遍历一遍就够了,这样就能把主函数的二重循环变成一重循环了。

  当然,还要注意一些细节,从中间往外走,这个中点可能是单独一个其左右相同,也可能和相邻的相同再往外扩,这两种情况分开处理就好,需要的是维护两个数字,一个是回文字符串最长的长度maxLen,第二个是回文字符串开始的index。代码如下:

 //从中间开始走起的O(n^2)搜索。
public class Solution { public String longestPalindrome(String s) {
if (s.length() == 0 || s.length() == 1) return s;
//数组里一个是maxLength,一个是最长回文字符串的head,每次都需要维护这个数组里的两个数。
int[] res = new int[2];
for (int i = 0; i < s.length(); i++) {
//中点是单独存在的情况。
extendPalindrome(s,i,i,res);
//中点和相邻是相等的情况。
extendPalindrome(s,i,i+1,res);
}
int maxLength = res[0];
int head = res[1];
return s.substring(head,head + maxLength - 1);
} private void extendPalindrome(String s, int left, int right,int[] res) {
//left网左走,right往右走直到走到边界或者他们不是回文为止。
while (left >= 0 && right <= s.length() - 1) {
if (s.charAt(left) != s.charAt(right)) break;
left--;
right++;
}
int length = right - left;
if (length > res[0]) {
res[0] = length;
//+1是因为while循环里是在left=-1或者是回文边界的前一个跳出。
res[1] = left + 1;
}
}
}

  通过查阅Leetcode里面的discusion,发现还有一种O(n)的方法,这个方法运用的是Manacher's Algorithm,这种算法是一种非平凡算法,它需要用到O(n)的空间和O(n)的时间,在面试的过程中并不需要想出来(也想不到。。。),但是却是一个非常有意思的算法,下面的链接我觉得是对这个算法解释的比较清晰的一篇文章,有空可以去看看,研究研究:

  http://blog.csdn.net/insistgogo/article/details/12287805

  

LeetCode(5) - Longest Palindromic Substring的更多相关文章

  1. 【一天一道LeetCode】#5 Longest Palindromic Substring

    一天一道LeetCode系列 (一)题目 Given a string S, find the longest palindromic substring in S. You may assume t ...

  2. 【LeetCode OJ】Longest Palindromic Substring

    题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 题目:Given a string S, find the long ...

  3. LeetCode(3)题解: Longest Palindromic Substring

    https://leetcode.com/problems/longest-palindromic-substring/ 题目: Given a string S, find the longest ...

  4. 【LeetCode】5. Longest Palindromic Substring 最长回文子串

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:最长回文子串,题解,leetcode, 力扣,python ...

  5. 【LeetCode】5. Longest Palindromic Substring 最大回文子串

    题目: Given a string S, find the longest palindromic substring in S. You may assume that the maximum l ...

  6. 【leetcode】5. Longest Palindromic Substring

    题目描述: Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  7. leetcode题解 5. Longest Palindromic Substring

    题目: Given a string s, find the longest palindromic substring in s. You may assume that the maximum l ...

  8. LeetCode OJ:Longest Palindromic Substring(最长的回文字串)

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  9. 【LeetCode】005. Longest Palindromic Substring

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

随机推荐

  1. Hbase源码分析:Hbase UI中Requests Per Second的具体含义

    Hbase源码分析:Hbase UI中Requests Per Second的具体含义 让运维加监控,被问到Requests Per Second(见下图)的具体含义是什么?我一时竟回答不上来,虽然大 ...

  2. STL笔记(5)条款49:学习破解有关STL的编译器诊断信息

    STL笔记(5)条款49:学习破解有关STL的编译器诊断信息 条款49:学习破解有关STL的编译器诊断信息 用一个特定的大小定义一个vector是完全合法的, vector<int> v( ...

  3. Android实现自定义字体

    介绍 最近在看开源项目的时候,发现里面涉及到了自定义字体,虽然自己目前还用不到,但是动手demo笔记记录一下还是有必要的,没准哪天需要到这个功能. 原理 1.其实实现起来非常简单,主要是用到了Type ...

  4. duilib库分析: 消息流程分析

      转 看下CWindowWnd类与CPaintManagerUI类是咋进行消息分发的吧. 1. 先看下CPaintManagerUI类的MessageLoop函数: void CPaintManag ...

  5. python Tkinter接受键盘输入并保存文件

    最近想用python写个切换host的小工具,折腾了好几天,终于实现了第一步. 采用Tkinter编程,text控件接受输入,然后点击save按钮,保存内容到当前文件夹下,文件名为hostb,如下两张 ...

  6. qt多文档

    http://blog.csdn.net/siren0203/article/details/5661541

  7. putty保持Session链接不断开的方法

    利用Putty登陆到远程主机后,如果长时间没有做任何操作,服务器会与本地客户端断开连接 假如设置了会话连接功能,就会每隔多少秒,客户端会发送一个空数据包给服务器,保持连接. 1. 打开putty.ex ...

  8. 字符串string

    1.字符串获取类.封装检测数字的方法 var str = '前端开发'; //alert(str.length); //alert(str.charAt()); //没有参数 取得索引是0 结果是:前 ...

  9. Java 中的二维数组

    所谓二维数组,可以简单的理解为是一种“特殊”的一维数组,它的每个数组空间中保存的是一个一维数组. 那么如何使用二维数组呢,步骤如下: 1. 声明数组并分配空间 或者 如: 2. 赋值 二维数组的赋值, ...

  10. blender2.7.4安装three.js插件

    将three.js-master\utils\exporters\blender\addons 下面的io_three文件夹,拷贝到blender安装目录:blender-2.74-windows64 ...