300、最长上升子序列
题目描述:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4
思路:利用动态规划
用dp[i] 表示 从下标0 到下标i 的最长上升子序列的长度,例如对于样例输入[10,9,2,5,3,7,101,18], 有 dp = [ 1, 1, 1, 2, 2, 3, 4, 4]。显然dp[0] = 1,对于任意的i 不为零的情况,应该在 i 的左侧找一个下标 j ,其满足两个条件:
1.nums[ j ]比 nums[ i ] 小;
2.它是所有满足条件1里 dp [j] 最大的那个;
即:dp[i] = max(dp[j] + 1,dp[i]) , j < i and nums[ j ] < nums[ i ]
如果不存在这样的下标j,说明在0 ~ i - 1 的范围内,所有元素都比nums[i] 大,即无法找到一个能和 nums[i] 组成上升子序列的元素,所以dp[i] = 1, 表示为nums[i] 自身成为一个长度为1 的上升子序列。
class Solution(object):
def lengthOfLIS(self, nums):
if not nums:
return 0
a = [1 for i in range(len(nums))] #单个元素的时候,最长序列为1
for i in range(1,len(nums)):
for j in range(0,i):
if nums[i] > nums[j]:
a[i] = max(a[j] + 1, a[i]) # i前边有j个元素的时候,需要确保a[i]的值能取到最大
return max(a)
nums = [10,9,2,2,3,3]
print(Solution().lengthOfLIS(nums))
总结:利用一个列表保存每一步的值,来降低重复计算量,这种动态规划方法经常用到,比如之前的爬楼梯或者跳台阶,都是同样的思想,当然我们也可以利用递归法来解决。
最后我们在列一下动态规划求解问题的四个特征:
①求一个问题的最优解;
②整体的问题的最优解是依赖于各个子问题的最优解;
③小问题之间还有相互重叠的更小的子问题;
④从上往下分析问题,从下往上求解问题;
本文深入探讨了求解最长上升子序列问题的动态规划方法,通过实例详细讲解了算法思路与实现过程,展示了如何利用动态规划降低重复计算量,提高效率。
688

被折叠的 条评论
为什么被折叠?



