300 最长上升子序列 (不连续,有顺序)
最长递增子序列
输入: [10,9,2,5,3,7,101,18]
输出: 4
【2,3,7,101】满足题意
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
def lengthOfLIS(self, nums: List[int]) -> int:
if not nums: return 0
n = len(nums)
dp = [1 for i in range(n)]
#dp[i] 所有元素置 1,含义是每个元素都至少可以单独成为子序列,此时长度都为 1
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) #返回 dp 列表最大值,即可得到全局最长上升子序列长度
#定义 dp[i] 为考虑前i个元素,以第i个数字结尾的最长上升子序列的长度,注意 nums[i] 必须被选取.
674 最长连续递增序列 (连续)
输入:【1,3,5,4,7】
输出:3
【1,3,5】满足题意
【1,3,5,7】不满足
def findLengthOfLCIS(nums):
if not nums: return 0
n = len(nums)
dp=[1]*n
for i in range(1,n):
if nums[i]>nums[i-1]:
dp[i]=dp[i-1]+1
return max(dp)
- 最长递增子序列的个数 (不连续) 2个动态规划
给定一个未排序的整数数组,找到最长递增子序列的个数。
输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
dp[i]表示以i位置结尾,即数组中以nums[i]结尾的最长连续递增序列长度;
dp_num[i]表示数组中以nums[i]结尾的最长连续递增的组合数量
例子:【1,2,4,3,5,4,7,2】
【1,2,4,5,7】、【1,2,3,5,7】、【1,2,3,4,7】以nums[6]=7结尾的dp_num =3
def findNumberOfLIS(self, nums: List[int]) -> int:
if not nums: return 0
n = len(nums)
max_ans = 1
dp = [1 for i in range(n)] #记录长度
dp_num = [1 for i in range(n)] #记录最长的个数
dp[0] = 1
for i in range(1,n):
for j in range(i):
if nums[i] > nums[j]:
if dp[j]+1>dp[i]:
dp[i] = dp[j]+1
max_ans = max(max_ans,dp[i])
dp_num[i] = dp_num[j] #组合数本身不变
elif dp[i] == dp[j] + 1: #说明最长的长度已经再次出现了,需要累加计次数
dp_num[i] += dp_num[j]
cnt = 0
for i in range(n):
if dp[i] == max_ans:
cnt += dp_num[i]
return cnt