题目
URL:https://leetcode.com/problems/longest-palindromic-substring
解法
一、循环搜索
对于每一个字符,往后搜索,遇到相同字符,开始判断是否回文串,若是回文串则与当前最长回文串的长度比较,若更长,则更新最长回文串。
显然是三层循环:第一层确定回文串起始位置,第二层确定回文串终止位置,第三层判断是否是回文串。
代码也比较简洁,可是循环太多。
public String longestPalindrome(String s) { String maxString = null; int maxLength = 0; for (int i = 0, left = i; i < s.length(); i++) { for (int j = i, right = j; j < s.length(); j++, left = i, right = j) { while (left < s.length() && right >= 0 && left < right && s.charAt(left) == s.charAt(right)) { left++; right--; } if (left >= right && j - i + 1 > maxLength) { maxLength = j - i + 1; maxString = s.substring(i, j + 1); } } } return maxString; }
循环搜索,时间复杂度O(n3),运行时间约为 TLE。
二、向外查找
对于每一个字符,假定它(回文串长度为奇数)或者它和它的右面字符(回文串长度为偶数)是回文串,那么我们只需要向外扩张,直到它不是回文串。
该算法其奥妙在于假定和向外扩张,而不是盲目搜索。
private int start; private int maxLength; public String longestPalindrome(String s) { if (s.length() == 0) return ""; for (int i = 0; i < s.length(); i++) { findPalindrome(s, i, i); findPalindrome(s, i, i + 1); } return s.substring(start, start + maxLength); } private void findPalindrome(String s, int left, int right) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { left--; right++; } if (right - left - 1 > maxLength) { start = left + 1; maxLength = right - left - 1; } }
向外查找,时间复杂度O(n2),运行时间约为 17 ms。
总结
有的时候思路要放开,不要太计算机思维(搜索),有时也要像现实一样思考。
时间: 2024-10-12 21:44:39