Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
1 public static string LongestPalindromicSubstring(string s) 2 { 3 if (s.Length <= 1) 4 return s; 5 string ret = ""; 6 7 //i is the length of substring which to test 8 for (int i = s.Length; i >= 2; i--) 9 { 10 for (int start = 0; start <= s.Length - i; start++) 11 { 12 string temp = s.Substring(start, i); 13 14 //put l, r pointers to the center of temp, i is odd, l = r 15 int l = start + i / 2 - 1; 16 int r = start + i / 2 + i % 2; 17 18 bool isP = true; 19 while (l >= start && r < start + i) 20 { 21 //if equal, l and r expand 22 if (s[l] == s[r]) 23 { 24 l--; 25 r++; 26 } 27 else 28 { 29 isP = false; 30 break; 31 } 32 } 33 if (isP) 34 return temp; 35 } 36 } 37 return ret; 38 }
代码分析:
一个O(n3)的解法。 有长至短,有左至右,test 每一个可能的substring。
例如:“banana”
1. 先看 "banana" 是否 palindromic.
2. 再看 "banan", "anana" (到这就找到最长的palindromic了)
3. 如果上面是没找到的,再看 "bana", "anan", "nana"
...
展开1: 判断是否palindromic
设两指针l, r, 分别指向substring 的中间,例如"banana", l -> "n" , r -> "a"。 如果substring 长度为奇数 "anana", l = r -> "a"。 再往两边扩张。
1 public static string LongestPalindromicSubstringOpt(string s) 2 { 3 if (s.Length <= 1) 4 return s; 5 6 //because if no palindromic, return the first letter 7 string ret = s.Substring(0, 1); 8 9 for (int i = 0; i < s.Length; i++) 10 { 11 string temp = expandCenter(s, i, i); 12 if (temp.Length > ret.Length) 13 ret = temp; 14 15 temp = expandCenter(s, i, i + 1); 16 if(temp.Length > ret.Length) 17 ret = temp; 18 } 19 20 return ret; 21 } 22 23 public static string expandCenter(string s, int c1, int c2) 24 { 25 int l = c1; 26 int r = c2; 27 int n = s.Length; 28 while (l >= 0 && r < n && s[l] == s[r]) 29 { 30 l--; 31 r++; 32 } 33 return s.Substring(l + 1, r - l - 1); 34 }
代码分析:
O(N2)的解法。找字符串每个可能的中间点展开,返回最长的palindromic,如果比之前的长,替换之。
例如:"banana" , 一开始缺省认为最长palindromic是第一个字母"b" (好像在这里有点多余...)
1. 从"b"展开, 最长palindromic 是"b"。ret = "b"在;
2. 从"ba"展开(中间点在"b"和"a"之间), 没有palindromic;
3. 从"a"展开,最长palindromic是"a", 不替换;
4. 从"an"展开,没有palindromic;
5. 从"n"展开,最长palindromic是"ana", 替换 ret = "ana";
6. 从"na"展开,没有palindromic;
7. 从"a"展开,最长palindromic是"anana", 替换 ret = "anana";
...
...
如果加一个flag,说最长的palindromic已经到达字符串最后一个字符,可以马上返回,这样可以稍稍提高点效率。
这一题是存在O(n)的解法的,应对面试上面的解法应该足够了。详细请看LEETCODE的Post。