难度中等6194收藏分享切换为英文接收动态反馈
给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
思考:我们首先可以考虑到遍历每个节点,然后从每个节点来向两边扩散判断以当前节点为“中心”的回文串,从中间往两边考虑回访串有两种情况1.abcba型,长度为奇数,中心为某个确定的节点 2.abba型,长度为偶数,中心为此字符串的中间两个字符之间。下面开始编写代码
public String longestPalindrome(String s) { String sMax = "";//用来存储结果 for (int i = 0; i < s.length(); i++) { //遍历每个节点,找到当前节点能够扩散的最大回文串 String sTemp = longestPalindromeByIndex(s, i); sMax=sMax.length()>=sTemp.length()?sMax:sTemp; } return sMax; } public String longestPalindromeByIndex(String s,int index){ //如果是当前index为中心的长度为奇数的回文串 String s1 = s.charAt(index)+""; int b = index+1; String s2 = ""; //因为我们在进入方法的时候不知道index为当前s字符串的前段还是后段,所以总是要考虑 //扩散后的字符串会不会超过s串的区域,所以我们用是否超出区域当作循环的结束情况 for (int i = 1;index-i>=0&&index+i<=s.length()-1; i++) { //从中心扩散开,每次扩散判断两边的字符是否相同,如果相同继续循环,如果不同,记录当前字符串的最大长度 //然后结束循环 if(s.charAt(index-i)!=s.charAt(index+i)){ s1 = s.substring(index-i+1,index+i); break; }else{ //如果出现一直到循环的结束了还是没有触发上面的if,由于循环就要结束,也要把当前最大的回文串记录下来 if(index+i==s.length()-1||index ==i){ s1 = s.substring(index-i,index+i+1); } } } //偶数长度同理,我们要从index 和index+1往两边扩散,不同的循环的开始我们就要判断中心的两个字符是否相同 for (int i = 0;index-i>=0&&b+i<=s.length()-1; i++) { if(s.charAt(index-i)!=s.charAt(b+i)){ s2 = s.substring(index-i+1,b+i); break; }else{ if(b+i==s.length()-1||index ==i){ s2 = s.substring(index-i,b+i+1); } } } return s1.length()>s2.length()?s1:s2; }
最后也是顺利通过
下面我们思考另一种方法,基于上面的方法我们每次对一个字符串进行遍历,每次要判断以当前节点能够形成的最大的回文串,这就导致了很多重复的判断,如果我们能把之前判断的结果用于下次判断,那应该能找到一种更好的解决方法,所以第二种方法我们尝试动态规划去解决。
不好意思,动态规划想了半天感觉好像还是上面方法的变形,不写了