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

你可能感兴趣的:(substring)