假定有字符数组 ababaabc 改成 # a # b # a # b # a # a # b # c # 将偶数数组变成奇数统一处理 索性改成 ^ # a # b # a # b # a # a # b # c # $,头尾清晰 这样就可以通过把每个字符作为回文子串的中心向两边扩展,找出最长回文子串 时间复杂度是 O(n^2)
private fun formatString(s: String): String{ val tString : StringBuffer = StringBuffer("^#") for ( i in s.indices ){ tString.append(s[i]) tString.append('#') } return tString.append('$').toString() } private fun extend(s: String, leftIndex: Int, rightIndex: Int): Int { var r = 0 varleft = leftIndex varright = rightIndex while (left > 0 && right < s.length && s[left] == s[right]){ r ++ left -- right ++ } return r } fun longestPalindrome(s: String): String { val tString = formatString(s) var maxR = 0 var maxCenter = 0 var center = -1 var R = 0 val p = Array<Int>(tString.length) { 0 } for ( i in tString.indices ){ val iMirror = center - (i - center) var rightIndex = i var leftIndex = i val maxLength = R - i val hasMirrorIndex = i < R && center - maxLength > 0 val case1CompletelyIncluded = hasMirrorIndex && i > center && p[iMirror] < R - i val case2NotCompletelyInclude = hasMirrorIndex && !case1CompletelyIncluded if(!hasMirrorIndex){ p[i] = 0 rightIndex = i + 1 leftIndex = i - 1 } else { if(case1CompletelyIncluded) { p[i] = p[iMirror] continue } else if (case2NotCompletelyInclude) { p[i] = maxLength rightIndex = R + 1 leftIndex = i - (rightIndex - i) } } p[i] += extend(tString, leftIndex, rightIndex) // 更新最右边的 R 和 center if(i + p[i] > R){ R = i + p[i] center = i } // 判断是不是最长的回文串 if(p[i] > maxR){ maxR = p[i] maxCenter = i } } if(maxR == 0) return "" val start = maxCenter - maxR val end = maxCenter + maxR return tString.substring(start..end).replace("#", "") } }