LeetCode-5LongestPalindromicSubstring(C#)

# 题目

5. 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.

# 思路

暴力破解(我和我同学也喜欢叫爆破):

固定下标,再固定长度,这样就能取出字符串。判断字符串是否是回文串且长度比原来的回文串长,若是,更新,若否,继续取字符串。

        // brute force: time O(n ^ 3) space O(n) result: TLE
        public string LongestPalindrome(string s)
        {
            char[] strs = s.ToCharArray();
            , end = ;

            ; i < strs.Length; i++) // start by index i
            {
                ; j > i; j--) // end by index j
                {
                    if (strs[i] == strs[j])
                    {
                        bool isPalindrome = true;
                        , l = j - ; k < l; k++, l--) // check whether substring is palindrome or not
                        {
                            if (strs[k] != strs[l])
                            {
                                isPalindrome = false;
                                break;
                            }
                        }

                        if (isPalindrome && j - i > end - start) // compare
                        {
                            start = i;
                            end = j;
                        }
                    }
                }
            }
            );
        }

暴力破解时间复杂度O(n ^ 3)空间复杂度O(n)时间TLE

我思维有点固化了。总想着先取字符串来判断是否是回文串,其实可以假定它是回文串,看它到底有多长。下面两个方法就是这样思考的。

优化暴力破解

对于每一个字符,分奇偶,分别尝试去找最长的回文串,并记录长度。

        // reference: https://discuss.leetcode.com/topic/23498/very-simple-clean-java-solution
        // optimize brute force: time O(n ^ 2) space O(n) result: 156ms
        public void palindrome(char[] strs, int left, int right, ref int start, ref int length) // judge palindrome
        {
             && right <= strs.Length -  && strs[left] != strs[right]) return;

             >=  && right +  <= strs.Length -  && strs[left - ] == strs[right + ])
            {
                left--;
                right++;
            }

            ;
            if (length < newLength)
            {
                start = left;
                length = newLength;
            }
        }

        // optimize brute force : time O(n ^ 2) space O(n) result:
        public string LongestPalindrome(string s)
        {
            ) return s;

            , length = ;
            char[] strs = s.ToCharArray();
            ; i < strs.Length; i++)
            {
                palindrome(strs, i, i, ref start, ref length); // recrusively judge
                palindrome(strs, i, i + , ref start, ref length);
            }
            return s.Substring(start, length);
        }

优化暴力破解时间复杂度O(n ^ 2)空间复杂度O(n)时间153ms

优化遍历
对于每一个字符,尝试去找最长的回文串,采取以下方法:
1、若是重复串,跳过重复部分(重复串怎么样都是回文串)。
2、非重复串,正常比对头尾。
3、设置下一个字符为非重复部分的下一个字符
比如baaaaab,遇到第一个a的时候,直接忽略5个a(也就是默认他是回文串了),从b开始尝试寻找回文串。同时下一个需要判断的字符是从第二个b开始。

# 解决(优化遍历)

        // reference: https://discuss.leetcode.com/topic/12187/simple-c-solution-8ms-13-lines/
        // like cheating method: time O(n ^ 2) space O(n) result: 132ms
        public string LongestPalindrome(string s)
        {
            char[] strs = s.ToCharArray();
            , maxLength = , start = ;

            )
            {
                int k = i, j = i; // j is left, i is middle, k is right
                 && strs[k] == strs[k + ]) k++; // skip duplicate char
                i = k + ; // set next begin index, we can skip duplicate char

                 && k < s.Length -  && strs[j - ] == strs[k + ]) // check palindrome
                {
                    j--;
                    k++;
                }

                ;
                if (newLength > maxLength) // compare
                {
                    start = j;
                    maxLength = newLength;
                }
            }

            return s.Substring(start, maxLength);
        }       

优化遍历时间复杂度O(n ^ 2)空间复杂度O(n)时间132ms

# 题外话

动态规划也可以做。

具体参考https://discuss.leetcode.com/topic/23498/very-simple-clean-java-solution/12。

状态转移方程:palindrome[i][j] = palindrome[i + 1][j - 1] && s[i] == s[j] 。palindrome[i][j]表示s[i]到s[j]是否是回文串。

题主太懒了,交给你们了。

# 测试用例

        static void Main(string[] args)
        {
            _5LongestPalindromicSubstring solution = new _5LongestPalindromicSubstring();
            Debug.Assert(solution.LongestPalindrome("dddddd") == "dddddd", "wrong 1");
            Debug.Assert(solution.LongestPalindrome("abbacdef") == "abba", "wrong 2");
            Debug.Assert(solution.LongestPalindrome("cabbadef") == "abba", "wrong 3");
            Debug.Assert(solution.LongestPalindrome("cabba") == "abba", "wrong 4");
            Debug.Assert(solution.LongestPalindrome("caacbbbbbad") == "bbbbb", "wrong 5");
            string veryLong = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
            Debug.Assert(solution.LongestPalindrome(veryLong) == veryLong, "wrong 6");
            Debug.Assert(solution.LongestPalindrome("a") == "a", "wrong 7");
            Debug.Assert(solution.LongestPalindrome("abb") == "bb", "wrong 8");
        }

# 地址

Q: https://leetcode.com/problems/longest-palindromic-substring/

A: https://github.com/mofadeyunduo/LeetCode/blob/master/5LongestPalindromicSubstring/5LongestPalindromicSubstring.cs

(希望各位多多支持本人刚刚建立的GitHub和博客,谢谢,有问题可以邮件609092186@qq.com或者留言,我尽快回复)

上一篇:mybatis 之 parameterType="Map"


下一篇:第四章 Spring.Net 如何管理您的类___对象的初始化方式