• LeetCode0005.最长回文子串


    题目要求

    算法分析

    暴力算法

    截取每一个子串 判断是否为回文串 输出其中最长的回文子串。

    中心扩展

    若回文串两侧的字符相同,则删去两侧字符后剩下的字符串仍为回文串。

    我们可以反过来,对字符串中的某一位字符c(或某两位相邻的相同字符串cc),

    如果其两侧字符相同,则让它向两侧扩展,直到两侧字符不同,最后便获得了以c(或cc)为中心的回文字串。

    对每一位都进行上述操作,便可获取最长的回文子串。

    代码展示(C#)

    public string LongestPalindrome(string s)
            {
                if(s.Length < 2)
                {
                    return s;
                }
                string result = "";
                int maxLength = 0;
                //"abcdefg"
                // i
                for (int i = 0; i < s.Length; i++) {
                    for (int j = 1; j <= s.Length - i; j++)
                    {
                        string temp = s.Substring(i, j);
                        if (IsPalindrome(temp)&& j > maxLength)
                        {
                            result = temp;
                            maxLength = j;
                        }
                    }
                }
    
                return result;
            }
    
            public bool IsPalindrome(string s)
            {
                bool result = true;
                int i = 0;
                int j = s.Length - 1;
                while (i < j)
                {
                    if (s[i++] != s[j--])
                    {
                        result = false;
                        break;
                    }
                }
                return result;
            }
    暴力算法[时间复杂度O(n3)超时]
    public class Solution {
        public string LongestPalindrome(string s)
        {
            if (s.Length < 2)
            {
                return s;
            }
            string result = "";
            int max = 0;
            int start = 0;
            //cbbd
            for (int i = 0; i < s.Length; i++)
            {
                int length1 = OneCentralExpansion(s, i);
                if (length1 > max)
                {
                    max = length1;
                    start = i - (max - 1) / 2;
                }
                if (i < s.Length - 1 && s[i] == s[i+1])
                {
                    int length2 = TwoCentralExpansion(s, i);
    
                    if (length2 > max)
                    {
                        max = length2;
                        start = i - (max - 1) / 2;
                    }
                }
            }
            result = s.Substring(start, max);
            return result;
        }
    
        /// <summary>
        /// 单字符扩展
        /// </summary>
        /// <param name="s">原字符串</param>
        /// <param name="center">子串中心字符的索引</param>
        /// <returns>回文子串长度</returns>
        public int OneCentralExpansion(string s,int center)
        {
            int result = 1;
            int left = center - 1;
            int right = center + 1;
            while (left >= 0 && right < s.Length)
            {
                if (s[left--] == s[right++])
                {
                    result += 2;
                }
                else
                {
                    break;
                }
            }
            return result;
        }
    
        /// <summary>
        /// 双字符扩展
        /// </summary>
        /// <param name="s">原字符串</param>
        /// <param name="center">子串中心字符串的第一个字符的索引</param>
        /// <returns>回文子串长度</returns>
        public int TwoCentralExpansion(string s, int center)
        {
            int result = 1 +1;
            int left = center - 1;
            int right = center + 1  +1;
            while (left >= 0 && right < s.Length)
            {
                if (s[left--] == s[right++])
                {
                    result += 2;
                }
                else
                {
                    break;
                }
            }
            return result;
        }
    }

    代码展示(C++)

    class Solution {
    public:
        string longestPalindrome(string s) {
            if (s.size() < 2) {
                return s;
            }
            string result = "";
            int max = 0;
            int start = 0;
            for (int i = 0; i < s.size(); ++i) {
                int length1 = CentralExpansion(s, i, 0);
                if (length1 > max) {
                    max = length1;
                    start = i - (max - 1) / 2;
                }
                if (i < s.size() - 1 && s[i] == s[i + 1]) {
                    int length2 = CentralExpansion(s, i, 1);
                    if (length2 > max) {
                        max = length2;
                        start = i - (max - 1) / 2;
                    }
                }
            }
            result = s.substr(start, max);
            return result;
        }
    
        int CentralExpansion(string s, int center, int plus) {
            int result = 1 + plus;
            int left = center - 1;
            int right = center + 1 + plus;
            while (left >= 0 && right < s.size()) {
                if (s[left--] == s[right++]) {
                    result += 2;
                }
                else {
                    break;
                }
            }
            return result;
        }
    };
    中心扩展

    提交结果

     

     

    一些感想

    代码写的过于冗杂,需要优化

  • 相关阅读:
    可持续化线段树(主席树)
    2016-06-19 NOIP模拟赛
    0618图的整理
    1536 海战
    1005 生日礼物
    3280 easyfinding
    2594 解药还是毒药
    2919 选择题
    1845 二叉查找树
    1174 靶形数独
  • 原文地址:https://www.cnblogs.com/KingR/p/12927446.html
Copyright © 2020-2023  润新知