【leetcode-Python】-Dynamic Programming-300. Longest Increasing Subsequence(LIS)

题目链接

https://leetcode.com/problems/longest-increasing-subsequence/

题目描述

给定整数数组nums,返回最长严格递增子序列的长度。子序列是由数组派生得到的,子序列中的元素相对顺序不会改变。如[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。

示例

Input:nums = [10,9,2,5,3,7,101,18]

Output: 4

最长严格递增子序列为[2,5,7,101],长度为4

 

输入:nums = [0,1,0,3,2,3]

输出:4

最长严格递增子序列为[0,1,2,3],长度为4

解题思路一

题目可用动态规划的思想来解决。定义d[i]为以nums[i]为末尾(必须包括)的最长递增子序列的长度。那么在已知d[0],d[1],...d[i-1]的情况下,能够推算出状态转移方程:d[i] = max(d[j])+1, 其中0<=j<i,且nums[j]<nums[i]。

状态d[i]将从d[j]转移过来,因此需要保证nums[j]<nums[i],这样nums[i]加入到nums[j]后才能构成严格递增子序列。最后返回d数组的元素最大值。

在代码实现过程中,需要双层for循环。第一层for循环更新d[i],第二层for循环找到符合条件的d[j]。

解决思路一Python实现

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int: 
        d = []
        result = 1
        for i in range(len(nums)):
            d.append(1)
            for j in range(i):
                if nums[j] < nums[i]:
                    d[i] = max(d[i],d[j]+1) #如果条件不被触发则d[i]等于1,如果条件被触发,d[i]等于d[j]+1的最大值
            result = max(result,d[i])
        return result

时间复杂度与空间复杂度

由于用到了双重循环,时间复杂度为O(n^2);

由于算法在执行过程中会开辟最长长度为n的数组d,因此空间复杂度为O(n)。

解题思路二

此题可借助Patience sorting来解决。耐心排序算法起源于一个纸牌游戏,在游戏中纸牌将按照一定的规则逐个被分到对应的pile里。排序的关键在于建桶和入桶规则:

建桶规则:如果当前没有桶或者不符合入桶规则,则新建一个桶。

入桶规则:只要比桶里最上边的数字小即可入桶,如果有多个桶可入,只放入最左侧的桶中。

在算法中,贪心策略体现在“每个数字放在符合入桶规则的最左侧的桶中”,在算法执行的任意步骤中,桶顶上的元素值都是从左到右递增的。

对于最长递增子序列问题,桶的个数就是最长递增子序列的长度。关于纸牌的例子详见Princeton lecture

下面用示例中的数组nums =  [10,9,2,5,3,7,101,18]来举例讲解算法步骤:

解题思路二Python实现

在代码实现过程中,用一个数组result存储所有的桶顶元素,在遍历给定的nums过程中更新result数组。具体算法流程如下:

(1)如果nums[i]> result[-1],说明需要新建一个桶,直接将nums[i]追加到result数组中。

(2)如果nums[i]<=result[-1],则在result数组中找到第一个不小于nums[i]的元素(由于result数组中元素为递增且为寻找下界,因此这里可以用二分搜索的第二个模板,参见【Leetcode-Python】-二分搜索模板汇总与相关题目),并用nums[i]替换掉该元素。

class Solution:
    def binarySearch(self,result,target): #返回result中第一个不小于target的元素 即是求x>= target的下界
        left,right = 0,len(result)
        while(left < right):
            mid = (left + right) // 2
            if (result[mid] == target):
                return mid
            elif(result[mid] < target):
                left = mid + 1
            else:
                right = mid
        return left #这里不用对nums[left]做判定, 因为一定是符合要求的。
        
    def lengthOfLIS(self, nums: List[int]) -> int:
        result = []
        for i in range(len(nums)):
            if len(result) == 0 or nums[i]>result[-1]:
                result.append(nums[i])
            else:
                target_index  = self.binarySearch(result,nums[i])
                result[target_index] = nums[i]
        return len(result)
        

时间复杂度与空间复杂度

遍历数组时间复杂度为O(n),执行二分搜索的时间复杂度为O(logn),因此整体算法的时间复杂度为O(nlogn)

由于算法在执行过程中会开辟最长长度为n的数组result,因此空间复杂度为O(n)。

拓展

如果需要进一步给出最长严格递增子序列的内容,解题思路二中得到的result数组即为结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值