《剑指offer》输出最长回文子串
来源:互联网 发布:涉密软件开发资质 编辑:程序博客网 时间:2024/06/05 07:25
题目:求字符串的最长回文子串。(说在前面的话:该题目实际来自于leetcode,由于本人目前主要刷剑指offer在,而牛客网剑指offer上面貌似没有该题目,而本人又觉得该题目不错,收录于此,并且尽力写的详实,与此与大家分享,希望对大家有所帮助)
温馨提示:寻求快速解答的童鞋们可以直接跳过扯蛋的解析一,去看解析二。
解析一:正如伟大的总设计师邓小平所说:“无论白猫还是黑猫,抓到老鼠就是好猫”。下面就讲解下该题目的其中一种解法,就是暴力的干了。直接求解该字符串的所有子串,每个子串都判断是否是回文,最后输出最大的回文子串。但是当我们躺在自己的编译器里面yy的时候,等你提交到leetcode上的时候,你就觉得杯具了,我了个去,超内存限制了。我的妈呀,我这是作了什么孽,这该是多大消耗啊,怎么办,看来此题的暴力法是夭折了。代码就不拿出来献丑了,下面介绍个比较“绅士”的解法。
解析二:该法叫做“中心扩展法”,类似于一个小破孩儿扔个石头在水塘里,然后水波以该石头为中心向四周扩散去。就像下面这样。
那么如何用该思想来求解该最大回文子串呢?
首先来看我们根据原串abcbaxy输出的最大子串是个什么东东了?
输入:abcbaxy
输出:abcba
用肉眼一看就知道是这个abcba,那么该串是如何撸出来的呢?总不能是看出来的吧。
其实,我们可以利用中心扩展法求解该题,意思是以第i个节点为水波的中心点,然后向字符串的两端扩散,当左边的字符串和右边的字符串相同的时候就继续,然后,怎么继续?那就是右边的游标继续向右+1,左边的游标向左-1,如果左右的字符串相等,又继续这样干下去。最后判断该区间的回文字符串长度是否大于初始化的max(max初始化为0)的值,如果大于就保存该左右游标了,然后把当前区间的长度赋予max。最后根据获得的最大回文子串的左右游标获取子串就是最大了。讲到这,大家可能还有点模糊。下面就画图说明下。
注意:用“中心法”求解的时候需要分两种情况,第一种是回文子串是奇数位,第二种是回文子串是偶数位置。
第一种:回文是奇数位
上图是举例当i=2时候,左边的游标left=i-1,右边的游标right=i+1,当左边指向的字符b和右边的b相同的时候就left–,right++。如下图
当条件超过范围left>=0&&left<right&&right<s.lenght()
就跳出
然后统计该区间的回文字符长度5是否大于max(max值初始化为0),如果大于,max=当前子串的长度5,然后保存当前的left以及right的值,方便以后计算最大的子串。
第二种:回文是偶数位
依然举例i=2,与奇数位回文不一样的是left=i,right=i+1,后面的计算原理同上。
当然talk is cheap,show me your code
/** * Created by wickedvalley on 2017/7/18. * 最长回文子串 */public class LongestPalindrome { //中心扩展法:总共有两种情况。第一种字符串为奇数,第二种字符串为偶数。无需判断字串的奇偶性,因为我们保存的是最大的回文字符串 //abcba //abccba public static String longestPalindrome(String s) { String result=""; int leftIndex=0; int rightIndex=0; int max=0; for(int i=0;i<s.length();i++){//子串为奇数 int left=i-1;//第i个字符串的左侧第一个字符 int right=i+1;//第i个字符串的右侧第一个字符 while (left>=0&&left<right&&right<s.length()){ if(s.charAt(left)==s.charAt(right)){//左侧与右侧相同 left--; right++; }else {//左侧与右侧不同的时候就跳出 break; } } ++left;//由于上边的循环都--了,该++了,恢复原来的位置 --right;//由于上边的循环最后都++了,该--了,恢复原来的位置 if((right-left+1)>=max){//该区间的回文长度大于最大的字符串长度,该记下相应的参数了 max=right-left+1; leftIndex=left; rightIndex=right; } } for(int i=0;i<s.length();i++){//子串为偶数 int left=i;//左边就是该字符串了 int right=i+1;//右边第一个需要与left位置的比较 while (left>=0&&left<right&&right<s.length()){ if(s.charAt(left)==s.charAt(right)){ left--; right++; }else { break; } } ++left;//理由均同上 --right; if((right-left+1)>=max){ max=right-left+1; leftIndex=left; rightIndex=right; } } result=s.substring(leftIndex,rightIndex+1);//需要注意,substring函数是左闭右开的,需要rightIndex+1 return result; } public static void main(String[] args) { System.out.println(longestPalindrome("abb"));//测试下 }}
- 《剑指offer》输出最长回文子串
- 原样输出最长回文子串
- 最长回文子串的输出
- 输出最长回文子串(找到最长回文子串,并输出最长回文子串)
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- lua next 用法 table 空的判断
- solr6.0以上安装完,http://localhost:8080/solr/index.html,报404错
- Java String 类
- HDU 1142 最短路径的数量
- HashMap 实现原理
- 《剑指offer》输出最长回文子串
- Spring Boot集成redis做数据缓存
- svn和git 配置忽略文件
- Python自动上京东抢手机
- JS代码放在head和body中的区别分析
- 多用户配置
- Spring 事务管理问题
- 括号配对问题
- 删除链表的重复结点