Leetcode_Dynamic_Programming -- 300. Longest Increasing Subsequence [medium]

Given an unsorted array of integers, find the length of longest increasing subsequence.

给定一个未排序的整数数组,返回该数组的最长递增子序列的长度。

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4 
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 

Note:

  • There may be more than one LIS combination, it is only necessary for you to return the length.
  • Your algorithm should run in O(n2) complexity.

注意:

这里可能不止一种最长递增子序列额组合,你只需要返回其长度

你的算法的时间复杂度应该在O(n^2)

Follow up: Could you improve it to O(n log n) time complexity?

能否将算法时间复杂度降低到O(nlogn)?

 

动态规划法,创建一个dp数组,题目要求最长递增子序列,所以初始化dp数组中元素应设置较小,然后向大的方向更新。可知最差情况是nums中第 i 个元素的最长递增子序列长度为1,则初始化dp数组全为1。

考虑边界情况nums为空,则加入判断,当nums为空时,返回0

这道题的状态转移方程该如何写,我们不妨来考虑dp[ i ]所代表的含义,dp[ i ]可以代表以nums中第 i 个元素结尾的数组最长递增子序列长度,也可以代表nums中前 i 个元素其最长递增子序列长度,这是两个完全不同的概念,请不要混淆!如果dp[ i ]代表nums中前 i 个元素最长递增子序列长度,是求不出问题的解的,仔细考虑的话就会发现,dp[ i ]与dp[ j ](0= < j < i)之间没有办法建立状态转移方程。只有当dp[ i ]代表以nums中第 i 个元素结尾的最长递增子序列长度,才会得到dp[ i ]与dp[ j ]之间的关联(0= < j < i),即比较nums[ i ]与nums[ j ]的大小(0= < j < i),判断dp[ i ]是否需要进行加一操作,不断更新dp[ i ]的大小,直到 j 从 0 遍历到 i-1为止,所以状态转移方程:

从0到 i 开始搜索,两层嵌套循环,比较nums[ i ]与当前数nums[ j ]的大小,更新dp[ i ], dp[ i ] = max(dp[ i ],dp[ j ]+1),j从0到 i,切记dp[ i ]代表的是 【 以nums[ i ]为结尾 】的最长递增子序列长度  。

Solutions:

Python

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        dp = [1]*len(nums)
        for i in range(1,len(nums)):
            for j in range(0,i):
                if nums[j]<nums[i]:
                    dp[i] = max(dp[i],dp[j]+1)
        return max(dp)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值