动态规划解法由于不用考虑中间结果的暂存,不用输出所有可能情况的集合,只需要求解问题的个数。所以dp很适合求解最大、最长系列问题。
最长递增子序列(LIS)
- leetcode300 LongestIncreaseSubsequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
For example, given [10, 9, 2, 5, 3, 7, 101, 18], the longest increasing subsequence is [2, 3, 7, 101].
Therefore the length is 4.
求解:
def find_LIS(nums):
"""
type:nums:list
rtype: int
"""
n = len(nums)
# 1. dp 定义
# dp[i] 为nums[i]对应能得到的最长递增子序列
# 2. dp 初始化
dp = [1 for i in range(n)]
res = 0
# 3. dp 递推
for i in range(1, n):
for j in range(i):
if nums[i] > nums[j] and dp[i] < dp[j] + 1:
#当前数比nums[j],可构成的最大递增子序列长度对j而言为dp[j]加1,这里我们要取小于nums[i]的最大j
# dp[i] 应该等于 max{dp[j]} 对应的那个 dp[j] + 1,且只增加一次, 前提是nums[j] < nums[i]
dp[i] = dp[j] + 1
res = max(res, dp[i])
return res
字符串中最长公共子序列(LCS):
- leecode1143 LongestCommonSubsequence
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
若这两个字符串没有公共子序列,则返回 0。
实例如下:
输入:text1 = “abcde”, text2 = “ace”
输出:3
解释:最长公共子序列是 “ace”,它的长度为 3。
- 1.dp定义
定义dp[i][j] 是字符串前缀s1[:i]与字符串s2[:j]得到的最长公共子串长度
- 2.dp初始化
dp[i,j] = 0
- 3.递推公式
if s1[i-1] == s2[j-1]:
# 当前字符相等时,在dp[i-1][j-1]的基础上加1
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i][j-1], dp[i-1][j])
最长回文子序列:
- leetcode516 longestPalindromeSubseq
最长回文子序列
bbbab 返回4
def longestPalindromeSubseq(self, s):
"""
:type s: str
:rtype: int
"""
# 1. dp定义
# 定义dp[i][j]为子串s[i:j]中包含的最长回文子串的长度
n = len(s)
dp = [[0 for j in range(n)] for i in range(n)]
# 2.dp初始化
# dp[i][i] = 1
for i in range(n):
dp[i][i] = 1
# 3.dp递推
for j in range(1, n):
for i in range(j-1, -1, -1): #注意递推顺序
if s[i] == s[j]:
# 此时结果为子串s[i+1:j-1]中包含的最长回文子串的长度加2
dp[i][j] = dp[i+1][j-1] + 2
else:
dp[i][j] = max(dp[i+1][j], dp[i][j-1])
return dp[0][n-1]
最大连续子序列和
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4], the contiguous subarray [4,−1,2,1] has the largest sum = 6.
- 1.dp定义
let dp[i] be the maximum subarray for an array with i elements.
即定义dp[i]为前i个元素的最大连续子序列和。
- 2.dp初始化
dp[0] = 0
dp[1] = nums[0]
- 3.dp递推
dp[i] = { dp[n-1] > 0 ? dp[n-1] : 0 } + nums[n-1]
更多精彩文章,欢迎关注公众号“Li的白日呓语”。