package com.ljp.test.leetcode;
/**
-
5. 最长回文子串
-
-
给你一个字符串 s,找到 s 中最长的回文子串。
-
-
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
-
-
-
示例 1:
-
-
输入:s = "babad"
-
输出:"bab"
-
解释:"aba" 同样是符合题意的答案。
-
示例 2:
-
-
输入:s = "cbbd"
-
输出:"bb"
-
-
提示:
-
-
1 <= s.length <= 1000
-
s 仅由数字和英文字母组成
-
-
来源:力扣(LeetCode)
-
链接:5. 最长回文子串
-
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 */ public class Number0005 {
public static void main(String[] args) { String s1 = "babad"; String s2 = "cbbd"; String s3 = "abcddcbaefghjk"; String s4 = "a"; String s5 = "abcd"; System.out.println(DynamicPlanning.longestPalindromicSubstring(s1)); System.out.println(DynamicPlanning.longestPalindromicSubstring(s2)); System.out.println(DynamicPlanning.longestPalindromicSubstring(s3)); System.out.println(DynamicPlanning.longestPalindromicSubstring(s4)); System.out.println(DynamicPlanning.longestPalindromicSubstring(s5)); System.out.println("---------------------------------------------"); System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s1)); System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s2)); System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s3)); System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s4)); System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s5)); }
/**
-
动态规划
-
三大步骤:
-
1、定义数组元素的含义:result[i][j]=true,表示下标i到下标j是当前字符串的回文子串
-
2、找出数组元素之间的关系式:result[i+1][j-1]=true and chars[i]==char[j]=true,则result[i][j]=true
-
3、找出初始值:result[i][i]=true chars[i]==char[i+1],则result[i][i+1]=true chars[i]==char[i+2],则result[i][i+2]=true */ private static class DynamicPlanning {
public static String longestPalindromicSubstring(String s) { int length = s.length(); if (length == 1) return s; boolean[][] result = new boolean[length][length]; // 最长回文字符串为1 for (int i = 0; i < length; i++) { result[i][i] = true; } char[] chars = s.toCharArray(); int begin = 0, maxLength = 1; // 最长回文字符串为2到length for (int n = 2; n < length; n++) { for (int i = 0; i < length; i++) { int j = i + n - 1; if (j >= length) { break; } if (chars[i] != chars[j]) { result[i][j] = false; } else { // 当子字符串长度为2和3时,必是子回文字符串 if (j - i < 3) { result[i][j] = true; } else { result[i][j] = result[i + 1][j - 1]; } } if (result[i][j] && j - i + 1 > maxLength) { begin = i; maxLength = j - i + 1; } } } return s.substring(begin, begin + maxLength); }
}
/**
-
中心扩展算法 */ private static class ExpandAroundCenter {
public static String longestPalindromicSubstring(String s) { int length = s.length(); if (length == 1) return s; int begin = 0, maxLength = 1; for (int i = 0; i < length; i++) { int l1 = expandAroundCenter(s, i, i); int l2 = expandAroundCenter(s, i, i + 1); int tempMaxLength = Math.max(l1, l2); if (maxLength < tempMaxLength) { maxLength = tempMaxLength; begin = i - (maxLength - 1) / 2; } } return s.substring(begin, begin + maxLength); }
private static int expandAroundCenter(String s, int left, int right) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { left--; right++; } // left多减了1,right多加了1.所以length=right-left+1-2=right-left-1 return right - left - 1; }
}
-
}