美文网首页
2020-11-05最长上升子序列

2020-11-05最长上升子序列

作者: Celia_QAQ | 来源:发表于2020-11-06 11:16 被阅读0次

    给定一个无序的整数数组,找到其中最长上升子序列的长度。

    示例:

    输入: [10,9,2,5,3,7,101,18]
    输出: 4 
    解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
    

    说明:

    可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
    你算法的时间复杂度应该为 O(n2) 。
    进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


    两种方法:动态规划0(n2)和贪心+二分查找0(n logn)
    最长上升子序列定义:
    就是给你一个序列,请你在其中求出一段不断严格上升的部分,它不一定要连续。

    就像这样:2,3,4,7和2,3,4,6就是序列2 5 3 4 1 7 6的两种选取方案。最长的长度是4


    image.png
    1、动态规划:(python3)
    class Solution:
        def lengthOfLIS(self, nums: List[int]) -> int:
            d = []
            for n in nums:
                if not d or n > d[-1]:
                    d.append(n)#元素加载最后一个元素
                else:
                    l, r = 0, len(d) - 1
                    loc = r
                    while l <= r:
                        mid = (l + r) // 2
                        if d[mid] >= n:
                            loc = mid
                            r = mid - 1
                        else:
                            l = mid + 1
                    d[loc] = n
            return len(d)
    

    作者:LeetCode-Solution
    链接:https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-by-leetcode-soluti/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    2、二分查找+贪心
    思路:
    image.png

    以输入序列 [0,8,4,12,2] 为例:
    第一步插入 0,d=[0];
    第二步插入 8,d=[0,8];
    第三步插入 4,d=[0,4];
    第四步插入 12,d=[0,4,12];
    第五步插入 2,d=[0,2,12]。
    最终得到最大递增子序列长度为 3

    作者:LeetCode-Solution
    链接:https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-by-leetcode-soluti/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    Krahets的博客(https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-dong-tai-gui-hua-2/)

    代码:(python3)

    class Solution:
        def lengthOfLIS(self, nums: [int]) -> int:
            tails, res = [0] * len(nums), 0
            for num in nums:
                i, j = 0, res
                while i < j:
                    m = (i + j) // 2
                    if tails[m] < num: i = m + 1 # 如果要求非严格递增,将此行 '<' 改为 '<=' 即可。
                    else: j = m
                tails[i] = num
                if j == res: res += 1
            return res
    

    相关文章

      网友评论

          本文标题:2020-11-05最长上升子序列

          本文链接:https://www.haomeiwen.com/subject/iwkovktx.html