刚考完试就开始做题了,debug了半天,晕= =, 开始吧
今天的题目要求我从一个String s中找到它里面的最长的“回文”substring。比如“abaefaf”里最长的回文substring是aba和faf,题目只要求我们返回一个最长的,所以返回哪个都可以。
题目很简单,但思路不太简单。我一开始的想法是,遍历整个string,把之前的char存在set或者stack之类的,但是好像这样不太好比较。那既然从一边往另一边算很难,那我就试试从中间开始吧,找到回文最中间的那个字符,或者最中间的两个(长度为偶数)。
首先初始化一个start代表回文的开头位置,longestLength代表这个string中最长的回文substring的长度,然后设置forloop,使i遍历string s。接着设置当前最长的回文长度currentLength。这时候我就需要知道每一个符合回文条件的长度。但首先还是要先确定回文substring的条件是什么才能找。
于是创建一个方法getLongestLength,参数分别为string s,代表回文最中间左右两边的left,right。现在就要开始构思回文的条件了,首先就要确保left和right要在string里,然后就是string在left位置和right位置的字符要一致,left,right分别递减和递增,由此找出最长的回文substring。找到回文后就返回right - left - 1作为该substring的长度。
回到主function,设置currentLength(即当前的回文substring长度)为呼叫getLongestLength后返回的值(如果string的长度是复数,回文中间的left和right就相等)。比较当前回文的长度和历史最长回文长度,如果当前的比较大,则将当前的存入历史最大,同时知道了我们也可以将start的值更新为i(即回文最中间的数)减去((回文的长度-1) 除以2)(即中间的数离start的距离)。
如此直到forloop结束,返回string s的substring(start, start + longestLength)即为答案
附上源码:
public class test { public static String longestPalindrome(String s) { int start = 0; int longestLength = 0; for (int i = 0; i < s.length(); i++){ int currentLength = Math.max(getLongestLength(s,i,i),getLongestLength(s,i,i+1)); if(currentLength > longestLength){ longestLength = currentLength; start = i - ((currentLength - 1) / 2); } } return s.substring(start, start + longestLength); } public static int getLongestLength(String s, int left, int right){ while((left >= 0) && (right < s.length()) && (s.charAt(left) == s.charAt(right))){ left--; right++; } return right - left - 1; } public static void main(String[] args){ System.out.println(longestPalindrome("babade")); } }