参考知乎一位作者的写法,有时间再改成c++.

链接:https://www.zhihu.com/question/330983016/answer/726069573

问题:

  马拉车用来搜索最长回文子串。

  普通的搜索方法为逐一的向两端扩展,时间复杂度是O(n*n)。

  马拉车算法的时间复杂度是线性的为O(n)。

 

 1 链接:https://www.zhihu.com/question/330983016/answer/726069573
 2 
 3 public String preProcess(String s) {
 4     int n = s.length();
 5     if (n == 0) {
 6         return "^$";
 7     }
 8     String ret = "^";
 9     for (int i = 0; i < n; i++)
10         ret += "#" + s.charAt(i);
11     ret += "#$";
12     return ret;
13 }
14 
15 // 马拉车算法
16 public String longestPalindrome2(String s) {
17     String T = preProcess(s);
18     int n = T.length();
19     int[] P = new int[n];
20     int C = 0, R = 0;
21     for (int i = 1; i < n - 1; i++) {
22         int i_mirror = 2 * C - i;
23         if (R > i) {
24             P[i] = Math.min(R - i, P[i_mirror]);// 防止超出 R
25         } else {
26             P[i] = 0;// 等于 R 的情况
27         }
28 
29         // 碰到之前讲的三种情况时候,需要利用中心扩展法
30         while (T.charAt(i + 1 + P[i]) == T.charAt(i - 1 - P[i])) {
31             P[i]++;
32         }
33 
34         // 判断是否需要更新 R
35         if (i + P[i] > R) {
36             C = i;
37             R = i + P[i];
38         }
39 
40     }
41 
42     // 找出 P 的最大值
43     int maxLen = 0;
44     int centerIndex = 0;
45     for (int i = 1; i < n - 1; i++) {
46         if (P[i] > maxLen) {
47             maxLen = P[i];
48             centerIndex = i;
49         }
50     }
51     int start = (centerIndex - maxLen) / 2; //最开始讲的求原字符串下标
52     return s.substring(start, start + maxLen);
53 }

 

posted on 2020-08-12 20:22  周伯通789  阅读(160)  评论(0编辑  收藏  举报