怎么判断一个字符串的最长回文子串是否在头尾_最长回文字串/子序列问题(leetcode5,9,519)
leetcode 5 最長回文子串
給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個有效答案。示例 2:
輸入: "cbbd" 輸出: "bb"思路:
動態規劃
為了改進暴力法,我們首先觀察如何避免在驗證回文時進行不必要的重復計算??紤]
這個示例。如果我們已經知道 是回文,那么很明顯, 一定是回文,因為它的左首字母和右尾字母是相同的。我們給出
的定義如下:因此,
基本示例如下:
這產生了一個直觀的動態規劃解法,我們首先初始化一字母和二字母的回文,然后找到所有三字母回文,并依此類推…
復雜度分析
- 時間復雜度:O(n^2)O(n2),這里給出我們的運行時間復雜度為 O(n^2)O(n2) 。
- 空間復雜度:O(n^2)O(n2),該方法使用 O(n^2)O(n2) 的空間來存儲表。
具體寫碼的時候用一個變量(代碼中的sub)來記錄目前最長的子串長度,用一個list(代碼中的max_len)來記錄最長子串的坐標
另一個leetcode上速度比較快的算法有點類似滑動窗口法,維護一個最大長度為lenth的窗口,并使用python語法糖q == q[::-1]來判斷是否是回文字符串,但是要注意的是維護窗口時要同時維護奇數和偶數兩種窗口。
答案:
class Solution(object):def longestPalindrome(self, s):""":type s: str:rtype: str"""n = len(s)if n == 0:return ''if n == 1:return sres = [[0 for _ in range(n)] for _ in range(n)]sub = 1max_len = [0,0]for i in range(n):res[i][i] = 1if i != n-1 and s[i] == s[i+1]:res[i][i+1] = 1sub = 2max_len=[i,i+1]for i in range(n):for j in range(1,min(i,n-i)+1):if i-j>=0 and i+j<n and res[i-j+1][i+j-1] and s[i-j]==s[i+j]:res[i-j][i+j] =1#print 1+2*jif sub<1+2*j:sub = 1+2*jmax_len = [i-j,i+j]#print sub,max_lenif i-j>=0 and i+1+j<n and res[i-j+1][i+j] and s[i-j] == s[i+j+1]:res[i-j][i+j+1] =1if sub<2+2*j:sub = 1+2*jmax_len = [i-j,i+j+1]#print sub,max_lenreturn s[max_len[0]:(max_len[1]+1)]class Solution(object):def longestPalindrome(self, s):""":type s: str:rtype: str"""if len(s) == 1 or s == s[::-1]:return sstart = 0length = 1for i in range(len(s)):p = s[i-length-1:i+1]q = s[i-length:i+1]if i-length-1 >= 0 and p == p[::-1]:start = i-length-1length += 2if i-length >=0 and q == q[::-1]:start = i - lengthlength += 1return s[start:start+length][647] 回文子串
給定一個字符串,你的任務是計算這個字符串中有多少個回文子串。
具有不同開始位置或結束位置的子串,即使是由相同的字符組成,也會被計為是不同的子串。
示例 1:
輸入: "abc"
輸出: 3
解釋: 三個回文子串: "a", "b", "c".
示例 2:
輸入: "aaa"
輸出: 6
說明: 6個回文子串: "a", "a", "a", "aa", "aa", "aaa".
注意:
輸入的字符串長度不會超過1000。
思路:
這道題的動態規劃思路跟上一道題(第五題)完全一樣,只不過在具體代碼的時候,使用一個變量來記錄回文子串的個數。
[516] 最長回文子序列
給定一個字符串s,找到其中最長的回文子序列。可以假設s的最大長度為1000。
示例 1:
輸入:
"bbbab"
輸出:
4
一個可能的最長回文子序列為 "bbbb"。
示例 2:
輸入:
"cbbd"
輸出:
2
一個可能的最長回文子序列為 "bb"。
思路:
這道題跟上兩道題的動態規劃思路完全不一樣,首先,這道題尋找的是最長回文子序列,子序列可以不相連。其次,這道題要返回的是最長回文子序列的長度,不關心子序列,所以構造動態規劃數組時也稍有不同。具體來說:
引入
,表示第i個字符至第j個字符組成的子串中最長回文子序列的長度。遞推公式可以表示為:
注意在具體代碼的時候,循環應該是先判斷間隔距離為1的所有字符對,然后依次增加。
答案:
class Solution(object):def longestPalindromeSubseq(self, s):""":type s: str:rtype: int"""n = len(s)if n<=1:return nif n==2:if s[0]==s[1]:return 2else:return 1resgrid = [[0 for _ in range(n)] for _ in range(n)]for i in range(n):resgrid[i][i]=1for gap in range(1,n):for i in range(n):if i+gap>=n:breakl = ih = i+gapif s[l]==s[h]:resgrid[l][h] = resgrid[l+1][h-1]+2else:resgrid[l][h]=max(resgrid[l+1][h],resgrid[l][h-1])return resgrid[0][n-1]總結
以上是生活随笔為你收集整理的怎么判断一个字符串的最长回文子串是否在头尾_最长回文字串/子序列问题(leetcode5,9,519)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java ejb项目_Maven创建EJ
- 下一篇: php链接javascript,java