字串dp系列

2021-10-06 21:58:17 字數 4132 閱讀 9765

647. 回文子串

給定乙個字串,你的任務是計算這個字串中有多少個回文子串。

具有不同開始位置或結束位置的子串,即使是由相同的字元組成,也會被計為是不同的子串。

示例 1:

輸入: "abc"

輸出: 3

解釋: 三個回文子串: "a", "b", "c".

示例 2:

輸入: "aaa"

輸出: 6

說明: 6個回文子串: "a", "a", "a", "aa", "aa", "aaa".

1.暴力,生成所有子串,乙個個判斷

2.dp[j][i]表示從j到i是否為回文串,如果s[j]==s[i],且dp[j+1][i-1]也是回文串,那麼dp[j][i]為真

其實dp也可以用來表示狀態,並不一定就是最後的結果!

class solution:

def countsubstrings(self, s: str) -> int:

res=

for i in range(len(s)):

for j in range(i,len(s)):

def func(s):

for i in range(len(s)//2):

if s[i]!=s[len(s)-1-i]:return false

return true

ans=0

for r in res:

if func(r):ans+=1

return ans

class solution:

def countsubstrings(self, s: str) -> int:

n=len(s)

res=0

dp=[[false for _ in range(n)] for _ in range(n)]

for j in range(n):

for i in range(j+1):

if ( j-i+1<=2 or dp[i+1][j-1] ) and s[i]==s[j]:

dp[i][j]=true

res+=1

return res

5. 最長回文子串

給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。

示例 1:

輸入: "babad"

輸出: "bab"

注意: "aba" 也是乙個有效答案。

示例 2:

輸入: "cbbd"

1.輸出: "bb"

1.dp[j][i]表示從j到i是否為回文串,如果s[j]==s[i],且dp[j+1][i-1]也是回文串,那麼dp[j][i]為真

2.中心擴充套件

class solution:

def longestpalindrome(self, s: str) -> str:

n=len(s)

dp=[[0]*n for _ in range(n)]

res=""

for i in range(n):

for j in range(i+1):

if s[i]==s[j] and (i-j+1<=3 or dp[j+1][i-1]):

dp[j][i]=1

res=max(res,s[j:i+1],key=len)

return res

class solution:

def longestpalindrome(self, s: str) -> str:

n=len(s)

self.res=""

def helper(i,j):

while i>=0 and j回文串通用dp思路,dp[i][j]表示區間【i,j】是否是回文串,dp[i][j]=true  if d[i+1][j-1]=true and s[i]==s[j],注意子串和子串行的區別。

300. 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。

示例:輸入: [10,9,2,5,3,7,101,18]

輸出: 4

解釋: 最長的上公升子串行是 [2,3,7,101],它的長度是 4。

說明:可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。

你演算法的時間複雜度應該為 o(n2) 。

高階: 你能將演算法的時間複雜度降低到 o(n log n) 嗎?

class solution:

def lengthoflis(self, nums: list[int]) -> int:

'''dp[i]=max(dp[j])+1 i>j and nums[i]>nums[j]

'''if not nums:return 0

n=len(nums)

dp=[1 for _ in range(n)]

for i in range(1,n):

for j in range(i):

if nums[i]>nums[j]:

dp[i]=max(dp[i],dp[j]+1)

return max(dp)

1143. 最長公共子串行

給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。

乙個字串的 子串行 是指這樣乙個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。

例如,"ace" 是 "abcde" 的子串行,但 "aec" 不是 "abcde" 的子串行。兩個字串的「公共子串行」是這兩個字串所共同擁有的子串行。

若這兩個字串沒有公共子串行,則返回 0。

示例 1:

輸入:text1 = "abcde", text2 = "ace"

輸出:3  

解釋:最長公共子串行是 "ace",它的長度為 3。

示例 2:

輸入:text1 = "abc", text2 = "abc"

輸出:3

解釋:最長公共子串行是 "abc",它的長度為 3。

示例 3:

輸入:text1 = "abc", text2 = "def"

輸出:0

解釋:兩個字串沒有公共子串行,返回 0。

class solution:

def longestcommonsubsequence(self, text1: str, text2: str) -> int:

'''dp[-1][-1]

dp[i][j]

'''m=len(text1)

n=len(text2)

dp=[[0 for _ in range(n+1)] for _ in range(m+1)]

for i in range(1,m+1):

for j in range(1,n+1):

if text1[i-1]==text2[j-1]:

dp[i][j]=dp[i-1][j-1]+1

else:

dp[i][j]=max(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])

return dp[-1][-1]

最長公共子串

def lcstring(string1,string2):

len1 = len(string1)

len2 = len(string2)

res = [[0 for i in range(len1+1)] for j in range(len2+1)]

result = 0

for i in range(1,len2+1):

for j in range(1,len1+1):

if string2[i-1] == string1[j-1]:

res[i][j] = res[i-1][j-1]+1

result = max(result,res[i][j])

return result

DP 字串變換

給定兩個字串,已知可以使用三種方式進行變換 1.插入乙個字元 2.刪除乙個字元 3.更改乙個字元 請設計乙個演算法,找到兩個字串之間的經歷幾次最小變換,可以字串1轉換成字串2 輸入描述 輸入兩個字串,字串的長度 1000輸出描述 最小變換次數示例1 hello helle1 include usin...

字串「最」系列

最近練手,整理了乙個 最 系列的主題,這些題目有點繞,個別的還有別名 詳見博文 混在一塊比較亂,就索性放在一起做了個整理,區別的時候要注意子串行與子串的不同,前者不要求連續,後者要求連續 由於大部分跟dp有關,而且一些題目還可以漸進尋求多種解法,可以用來做不錯的練手。下面是這些問題的博文目錄 1 最...

字串系列 word search

題目 已知 乙個二維字元矩陣,乙個單詞 輸出 該單詞是否可以從二維矩陣中拼接出來?拼接規則 從矩陣的某一行的某個字母開始,持續向臨近的字元擴充套件 向上,向下,向左,向右 直至拼接出該單詞。若可以拼出,則輸出false,若拼不出,則輸出false 例如 a,b,c,d,e e,f,g,h,u a,b...