题目描述
对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
示例
输入
"abc1234321ab",12
返回值
7
解题思路
- 将大问题拆分成小问题,回文子串每每去掉头部和尾部,都会是一个回文子串,向卷心菜一样剥开还是一个小的卷心菜,所以我们要从回文子串最中心着手。
- 我们要做的就是遍历回文子串的“中心”,得到中心之后再向外扩散,直到最外层数值不相等。
- 因为回文子串的中心可能有 1 个,如 "aba",也有可能是 2 个, 如 "abba",所以我们每次遍历中心时都要计算这两种情况,取这两种情况中子串最长的那个数。
Java代码实现
public class Solution { public int getLongestPalindrome(String A, int n) { char[] cArr = A.toCharArray(); int max = 1; // 遍历数组,获得回文子串的中心 for (int i = 0; i < n - 1; ++i) { // 假设中心只有一个点,向外扩散获得回文子串的长度 int a = calc(cArr, i, i); // 假设中心有两个点,…… int b = calc(cArr, i, i + 1); // 记录最长回文子串 int currentMax = a > b ? a : b; max = currentMax > max ? currentMax : max; } return max; } private int calc(char[] cArr, int low, int high) { /* 当中心为 1 个点,回文子串初始长度为 1,若为 2 个点,则初始长度为 0 因为 1 个点的情况如 "abc",中心点 b 长度就必定是 1 2 个点如 "abcd" 或 "abbc",中心点有可能是 "bc" 或 "bb" ,不能保证一致,所以长度为 0 */ int count = 1 ^ (high - low); if (low == high) { --low; ++high; } while (low >= 0 && high < cArr.length) { if (cArr[low] == cArr[high]) { --low; ++high; count += 2; } else { break; } } return count; } }