动态规划整理
1.最长公共子序列
# 给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列。
#
# 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
# 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde"
# 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
#
# 若这两个字符串没有公共子序列,则返回 0。
# 示例 1:
#
# 输入:text1 = "abcde", text2 = "ace"
# 输出:3
# 解释:最长公共子序列是 "ace",它的长度为 3。
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
"""
:type text1: str
:type text2: str
:rtype: int
"""
m,n=len(text1),len(text2)
dp=[[0 for _ in range(m+1)] for _ in range(n+1)]
for i in range(1,n+1):
for j in range(1,m+1):
str1=text1[:j]
str2=text2[:i]
if str1[-1]==str2[-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[-1][-1]
2.最长上升子序列
# 给定一个无序的整数数组,找到其中最长上升子序列的长度。
#
# 示例:
#
# 输入: [10,9,2,5,3,7,101,18]
# 输出: 4
# 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
#
# 说明:
# 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
# 你算法的时间复杂度应该为 O(n^2) 。
#
#
# 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:return 0
dp=[1]*len(nums)
for i in range(1,len(nums)):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i],dp[j] + 1)
# 最后要全部走一遍,看最大值
return max(dp)
3.爬楼梯
# 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
#
# 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
#
# 注意:给定 n 是一个正整数。
def climbStairs2(self, n):
if n == 1:
return 1
res = [0 for i in xrange(n)]
res[0], res[1] = 1, 2
for i in xrange(2, n):
res[i] = res[i-1] + res[i-2]
return res[-1]
4.最长公共子串
#给两个字符串,返回它们的最长公共子串的长度
class Solution(object):
def LCS(self,str1,str2):
if not str1 or not str2:return 0
dp=[[0 for _ in range(len(str1))] for _ in range(len(str2))]
res=0
for j in range(len(str1)):
if str1[j]==str2[0]:
dp[0][j]=1
for i in range(len(str2)):
if str2[i]==str1[0]:
dp[i][0]=1
for i in range(1,len(str2)):
for j in range(1,len(str1)):
if str1[j]==str2[i]:
dp[i][j]=dp[i-1][j-1]+1
res=max(res,dp[i][j])
return res