LeetCode Online Judge 题目C# 练习 - Longest Palindromic Substring

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

posted @ 2012-09-20 05:37  ETCOW  阅读(417)  评论(0编辑  收藏  举报