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)):
res.append(s[i:j+1])
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:
'''
dp[i][j]=true if dp[i+1][j-1] and s[i]==s[j]
'''
res=""
n=len(s)
dp=[ [False for _ in range(n)] for _ in range(n)]
for i in range(n):
dp[i][i]=True
for j in range(n):
for i in range(j):
if (j-i+1<=2 or dp[i+1][j-1] ) and s[i]==s[j]:
dp[i][j]=True
if j-i+1>len(res):
res=s[i:j+1]
return res if res else s[0]
class Solution:
def longestPalindrome(self, s: str) -> str:
n=len(s)
self.res=""
def helper(i,j):
while i>=0 and j<n and s[i]==s[j]:
i-=1
j+=1
if len(self.res)<j-i-1:
self.res=s[i+1:j]
for i in range(n):
helper(i,i)
helper(i,i+1)
return self.res
回文串通用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(object):
def longestCommonSubsequence(self, text1, text2):
M, N = len(text1), len(text2)
dp = [[0] * (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], dp[i][j - 1])
return dp[M][N]
最长公共子串
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