1 /** 2 * 最长回文子字符串 3 * 4 * @author 林夕 5 */ 6 public class Solution { 7 8 public static void main(String[] args) { 9 // String s = 10 // "rgczcpratwyqxaszbuwwcadruayhasynuxnakpmsyhxzlnxmdtsqqlmwnbxvmgvllafrpmlfuqpbhjddmhmbcgmlyeypkfpreddyencsdmgxysctpubvgeedhurvizgqxclhpfrvxggrowaynrtuwvvvwnqlowdihtrdzjffrgoeqivnprdnpvfjuhycpfydjcpfcnkpyujljiesmuxhtizzvwhvpqylvcirwqsmpptyhcqybstsfgjadicwzycswwmpluvzqdvnhkcofptqrzgjqtbvbdxylrylinspncrkxclykccbwridpqckstxdjawvziucrswpsfmisqiozworibeycuarcidbljslwbalcemgymnsxfziattdylrulwrybzztoxhevsdnvvljfzzrgcmagshucoalfiuapgzpqgjjgqsmcvtdsvehewrvtkeqwgmatqdpwlayjcxcavjmgpdyklrjcqvxjqbjucfubgmgpkfdxznkhcejscymuildfnuxwmuklntnyycdcscioimenaeohgpbcpogyifcsatfxeslstkjclauqmywacizyapxlgtcchlxkvygzeucwalhvhbwkvbceqajstxzzppcxoanhyfkgwaelsfdeeviqogjpresnoacegfeejyychabkhszcokdxpaqrprwfdahjqkfptwpeykgumyemgkccynxuvbdpjlrbgqtcqulxodurugofuwzudnhgxdrbbxtrvdnlodyhsifvyspejenpdckevzqrexplpcqtwtxlimfrsjumiygqeemhihcxyngsemcolrnlyhqlbqbcestadoxtrdvcgucntjnfavylip"; 11 String s = "babcbabcbaccba"; 12 // System.out.println(isPalindrome(s)); 13 long sTime = System.currentTimeMillis(); 14 String t = method4(s); 15 // String t = longestPalindrome(s); 16 long eTime = System.currentTimeMillis(); 17 System.out.println(t); 18 System.out.println("执行时间为" + (eTime - sTime) + "ms"); // 执行时间为75ms 19 } 20 21 /** 22 * 非常规情况:多个最长回文子字符串长度相等 ? 最笨的办法 时间复杂度为O(n^3) 23 * 本身有n^2个字符串,检查一个子串是否为回文串又需要O(n)的时间 24 */ 25 public static String longestPalindrome(String s) { 26 int l = s.length(); 27 String res = null; 28 int max = Integer.MIN_VALUE; 29 for (int i = 0; i < l; i++) { 30 for (int j = i; j < l; j++) { 31 String temp = s.substring(i, j + 1); 32 if (isPalindrome(temp)) { 33 if (temp.length() > max) { 34 max = temp.length(); 35 res = temp; 36 } 37 } 38 } 39 } 40 return res; 41 } 42 43 /** 44 * 判断是否为回文字符串 45 */ 46 public static boolean isPalindrome(String s) { 47 int l = s.length(); 48 int temp = (int) Math.floor((double) l / 2); // floor为向下取整 49 for (int i = 0; i < temp; i++) { 50 if (s.charAt(i) != s.charAt(l - 1 - i)) { 51 return false; 52 } 53 } 54 return true; 55 } 56 57 /** 58 * 时间复杂度:O(n^2) 空间复杂度:O(n^2) 59 * 算法理解:http://articles.leetcode.com/longest-palindromic-substring-part-i 60 */ 61 public static String method2(String s) { 62 int n = s.length(); 63 int longestBegin = 0; 64 int maxLen = 1; 65 boolean[][] table = new boolean[1000][1000]; 66 for (int i = 0; i < 1000; i++) { 67 for (int j = 0; j < 1000; j++) { 68 table[i][j] = false; 69 } 70 } 71 72 for (int i = 0; i < 1000; i++) { 73 table[i][i] = true; 74 } 75 76 for (int i = 0; i < n - 1; i++) { 77 if (s.charAt(i) == s.charAt(i + 1)) { 78 table[i][i + 1] = true; 79 longestBegin = i; 80 maxLen = 2; 81 } 82 } 83 84 for (int len = 3; len <= n; len++) { 85 for (int i = 0; i < n - len + 1; i++) { 86 int j = i + len - 1; 87 if (s.charAt(i) == s.charAt(j) && table[i + 1][j - 1]) { 88 table[i][j] = true; 89 longestBegin = i; 90 maxLen = len; 91 } 92 } 93 } 94 return s.substring(longestBegin, longestBegin + maxLen); 95 } 96 97 /** 98 * 时间复杂度:O(n^2) 有2N-1个Center 空间复杂度:O(1) 99 */ 100 public static String method3(String s) { 101 int n = s.length(); 102 if (n == 0) { 103 return ""; 104 } 105 String longest = s.substring(0, 1); 106 for (int i = 0; i < n - 1; i++) { 107 String p1 = expandAroundCenter(s, i, i); 108 if (p1.length() > longest.length()) { 109 longest = p1; 110 } 111 112 String p2 = expandAroundCenter(s, i, i + 1); 113 if (p2.length() > longest.length()) { 114 longest = p2; 115 } 116 } 117 return longest; 118 } 119 120 /** 121 * 辅助函数 以c1,c2为中心扩展字符串 122 * 123 * @param s 124 * @param c1 125 * @param c2 126 * @return 127 */ 128 public static String expandAroundCenter(String s, int c1, int c2) { 129 int l = c1, r = c2; 130 int n = s.length(); 131 while (l >= 0 && r <= n - 1 && s.charAt(l) == s.charAt(r)) { 132 l--; 133 r++; 134 } 135 return s.substring(l + 1, r); 136 } 137 138 /** 139 * 时间复杂度:O(n) 空间复杂度:O(n) Manacher’s algorithm 140 * http://articles.leetcode.com/longest-palindromic-substring-part-ii 141 */ 142 public static String method4(String s) { 143 String T = preProcess(s); 144 int n = T.length(); 145 int[] P = new int[n]; 146 int C = 0, R = 0; 147 for (int i = 1; i < n - 1; i++) { 148 int i_mirror = 2 * C - i; 149 P[i] = (R > i) ? Math.min(R - i, P[i_mirror]) : 0; 150 151 while (T.charAt(i + 1 + P[i]) == T.charAt(i - 1 - P[i])) 152 P[i]++; 153 154 // If palindrome centered at i expand past R, 155 // adjust center based on expanded palindrome. 156 if (i + P[i] > R) { 157 C = i; 158 R = i + P[i]; 159 } 160 } 161 // Find the maximum element in P. 162 int maxLen = 0; 163 int centerIndex = 0; 164 for (int i = 0; i < n - 1; i++) { 165 if (P[i] > maxLen) { 166 maxLen = P[i]; 167 centerIndex = i; 168 } 169 } 170 171 return s.substring((centerIndex - 1 - maxLen) / 2, (centerIndex - 1 + maxLen) / 2); 172 } 173 174 private static String preProcess(String s) { 175 int n = s.length(); 176 if (n == 0) { 177 return "^$"; 178 } 179 String ret = "^"; 180 181 for (int i = 0; i < n; i++) 182 ret += "#" + s.substring(i, i + 1); 183 184 ret += "#$"; 185 return ret; 186 187 } 188 189 }
时间: 2024-10-01 04:34:12