码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode oj s_05 最长回文子串

时间:2016-07-04 21:51:26      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

  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 }

 

leetcode oj s_05 最长回文子串

标签:

原文地址:http://www.cnblogs.com/LinXiYohoo/p/5641692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!