• [leetcode]Longest Palindromic Substring


     此题我曾经做过类似的(http://hi.baidu.com/lautsie/item/459a182eeddc568e6f2cc34a)但还是忘了,可见这个算法还是很tricky的。其实O(n^2)的算法还是能想到的,就是遍历每个字符,然后从该字符向两旁扩,寻找最长子串。但居然有O(n)的方法,见下面链接。

    http://www.felix021.com/blog/read.php?2040

    最后的代码其实可以做优化,比如最后不需要再遍历一边p[],但复杂度不变,又不是关键,就这样吧~

    public class Solution {
        public String longestPalindrome(String s) {
            // Start typing your Java solution below
            // DO NOT write main() function
            StringBuilder sb = new StringBuilder();
            sb.append('#');
            for (int i = 0; i < s.length(); i++)
            {
                sb.append(s.charAt(i));
            	sb.append('#');
            }
            
            String ss = sb.toString();
            int[] p = new int[ss.length()];
            int mx = 0;
            int id = 0;
            for (int i = 0; i < ss.length(); i++)
            {
            	p[i] = mx > i ? Math.min(p[id * 2 -i], mx - i) : 1;
            	while (i+p[i] < ss.length() && i - p[i] >=0)
            	{
            		if (ss.charAt(i + p[i]) == ss.charAt(i-p[i]))
            		{
            			p[i]++;
            		}
            		else
            		{
            			break;
            		}
            	}
            	if (i + p[i] > mx)
            	{
            		mx = i + p[i];
            		id = i;
            	}
            }
            
            // process result
            int maxIndex = 0;
            int maxLen = 0;
            for (int i = 0; i < ss.length(); i++)
            {
            	if( p[i] > maxLen)
            	{
            		maxLen = p[i];
            		maxIndex = i;
            	}
            }
            StringBuilder r = new StringBuilder();
            for (int i = maxIndex - p[maxIndex] + 1; i <= maxIndex + p[maxIndex] - 1; i++)
            {
            	if(ss.charAt(i) != '#')
            	{
            		r.append(ss.charAt(i));
            	}
            }
            return r.toString();
        }
    }
    

    第二刷,不强求用Manacher方法。使用n^2的方法,要注意长度为奇数和偶数两种情况。

    class Solution {
    public:
        string longestPalindrome(string s) {
            int maxLen = 0;
            int idx = 0;
            for (int i = 0; i < s.length(); i++)
            {
                for (int len = 0; i - len >= 0 && i+len < s.length(); len++)
                {
                    if (s[i-len] != s[i+len])
                        break;
                    if (maxLen < len * 2 + 1)
                    {
                        maxLen = len * 2 + 1;
                        idx = i - len;
                    }
                }
                for (int len = 0; i - len >= 0 && i+len+1 < s.length(); len++)
                {
                    if (s[i-len] != s[i+len+1])
                        break;
                    if (maxLen < (len + 1) * 2)
                    {
                        maxLen = (len + 1) * 2;
                        idx = i - len;
                    }
                }
            }
            return s.substr(idx, maxLen);
        }
    };
    

    python3的dp,最后超时了。还是中心扩散法好。

    class Solution:
        def longestPalindrome(self, s: str) -> str:
            palindromeDict = {}
            result = ''
            length = 1
            while length <= len(s):
                for idx in range(len(s)):
                    if idx + length <= len(s):
                        if length == 1:
                            palindromeDict[(idx, length)] = True
                            if palindromeDict[(idx, length)] and length > len(result):
                                result = s[idx : idx + length]
                        elif length == 2:
                            palindromeDict[(idx, length)] = (s[idx] == s[idx + 1])
                            if palindromeDict[(idx, length)] and length > len(result):
                                result = s[idx : idx + length]
                        else: # length > 2
                            palindromeDict[(idx, length)] = (s[idx] == s[idx + length - 1]) and palindromeDict[(idx + 1, length - 2)]
                            if palindromeDict[(idx, length)] and length > len(result):
                                result = s[idx : idx + length]
                            
                length += 1
                
            return result
            
            
    

    Python3的中心扩散法

    class Solution:
        def longestPalindrome(self, s: str) -> str:
            result = ''
            for i in range(len(s) * 2 - 1):
                center = i // 2
                if i % 2 == 1:
                    left = center
                    right = center + 1
                else: # i % 2 == 0
                    left = center
                    right = center
                while left >= 0 and right < len(s):
                    if s[left] == s[right]:
                        if right - left + 1 > len(result):
                            result = s[left : right + 1]
                        left -= 1
                        right += 1
                    else:
                        break
                    
                
            return result
            
            
    

      

  • 相关阅读:
    SQLServer之删除索引
    SQLServer之修改索引
    SQLServer之创建辅助XML索引
    SQLServer之创建主XML索引
    SQLServer之创建全文索引
    SQLServer之创建唯一非聚集索引
    SQLServer之创建唯一聚集索引
    SQLServer之创建非聚集索引
    SQLServer之添加聚集索引
    给NSMutableArray添加copy属性就变成了NSArray
  • 原文地址:https://www.cnblogs.com/lautsie/p/3194675.html
Copyright © 2020-2023  润新知