• leetcode算法刷题(三)


    今天在刷了几道简单的动态规划后,又看了看string方面的题

    第五题 Longest Palindromic Substring

    题目的意思:求一个字符串的最长回文子串
    分析:开始,我的想法是,现在字符串中插入特殊字符,比如'$',这样可以规避回
    文串长度为奇数或偶数的讨论问题,加入特殊字符后,长度始终为奇数。然后建立一个数组,该数组记录了以每一位为中心的回文字符串的长度。解法很简单:

    def findmin(s): 
    	s_ = '~' + '~'.join(s) + '~' 
    	st = '' 
    	p = [0 for i in range(len(s_))] 
    	for i in range(len(s_)): 
    		if i == 0 or i == len(s_)-1: 
    			p[i] = 1
    		else: 
    			temp = 0 
    			for j in range(min(i, len(s_)-i-1)+1): 
    				if s_[i-j] != s_[i+j]:
    					break 
    				temp += 1 
    			p[i] = temp 
    	position = p.index(max(p))
        for i in range(max(p)):
            if s_[position+i] != '~':
                st += s_[position+i]
        if (max(p)-1) % 2 == 0:
            st = st[::-1] + st
        else:
            st = st[:0:-1] + st
        return st
    

    可是提交上去后,结果是运行超时...(时间复杂度比较高,没通过) 然后我百度了一下这个问题,找到了一个比较nb的算法,复杂度为O(n)
    Manacher算法: 一开始和我的想法类似,填充特殊字符,保证回文串长度为奇数。Manacher算法用一个辅助数组p[i]表示以字符T[i]为中心的最长回文字串的最右字符到T[i]的长度,比如以T[i]为中心的最长回文字串是T[l,r],那么p[i]=r-i+1。p[i]-1就是该回文子串在原字符串S中的长度。
    Len数组的计算 首先从左往右依次计算p[i],当计算p[i]时,pj已经计算完毕。设P为之前计算中最长回文子串的右端点的最大值,并且设取得这个最大值的位置为id

    总结一下,Manacher算法通过记录已匹配的最右位置和对应的对称中心来跳过一些没用的比较

    class Solution: 
    	@param {string} s
    	@return {string} 
    	def longestPalindrome(self, s): 
    		s ='$'+'$'.join(s)+'$' 
    		mx = 0 #之前计算的最长的回文子串长度所能到达的最后边界 
    		id_ = 0 #mx对应的中心 
    		p = [0 for i in range(len(s))] 
    		st = '' 
    		for i in range(len(s)): 
    			#i在边界内 
    			if mx > i: 
    				p[i] = min(p[2*id_-i], mx-i) 
    			#i在边界外,需要从头开始匹配 
    			else: 
    				p[i] = 1 
    			while i-p[i] >= 0 and i+p[i] < len(s) and s[i-p[i]] == s[i+p[i]]: 
    				p[i] += 1
    			#如果新计算的回文串右端点位置大于mx,需要更新mx与id_ 
    			if mx < p[i] +i: 
    				mx = p[i] +i 
    				id_ = i 
    			#输出字符串
    			position = p.index(max(p)) 
    			for i in range(max(p)): 
    				if s[position+i] != '$': 
    					st += s[position+i] 
    			if (max(p)-1) % 2 == 0: 
    				st = st[::-1] + st 
    			else: 
    				st =st[:0:-1] + st 
    		return st 
    
  • 相关阅读:
    hdu 2553 N皇后问题(dfs)
    hdu 1043 Eight(双向bfs)
    牛人的ACM经验 (转)
    康托和逆康托展开(转)
    hiho Mission Impossible 6(模拟 未提交验证。。)
    数组越界也可以这么巧~~~
    poj 1679 The Unique MST(次小生成树)
    zoj 3204 Connect them(最小生成树)
    hdu 4463 Outlets(最小生成树)
    廖雪峰Java1-2程序基础-8字符和字符串
  • 原文地址:https://www.cnblogs.com/eric-nirnava/p/leetcode3.html
Copyright © 2020-2023  润新知