zoukankan      html  css  js  c++  java
  • LeetCode 300——最长上升子序列

    1. 题目

    2. 解答

    2.1. 动态规划

    我们定义状态 state[i] 表示以 nums[i] 为结尾元素的最长上升子序列的长度,那么状态转移方程为:

    [state[i] = max(state[j] + 1) space 如果 space nums[i] > nums[j], 0 leqslant j < i ]

    class Solution {
    public:
    
        int lengthOfLIS(vector<int>& nums) {
    
            int n = nums.size();
            vector<int> state(n, 1);
    
            for (int i = 1; i < n; i++)
            {
                for (int j = i-1; j >= 0; j--)
                {
                    if (nums[i] > nums[j])
                        state[i] = max(state[i], state[j]+1);
                }
            }
    
            int ret = 0;
            for (int i = 0; i < n; i++)
                ret = max(ret, state[i]);
            return ret;
        }
    };
    

    易知上面代码的时间复杂度为 (O(n^2))

    2.2. 贪心思想

    我们用一个列表 result 来放置我们的最长上升子序列,然后向后遍历数组,如果 nums[i] > result[-1],说明当前元素应该被放进列表中去,因为这样就能组成一个更长的上升子序列;如果 nums[i] < result[-1],说明目前的上升子序列里面有大于当前元素的数据,贪心思想是说让我们用当前元素去替换掉上升子序列里面第一个大于等于当前元素的数,这样我们就可以有更大的操作空间去向 result 里面放更多的元素,从而形成更长的上升子序列

    比如 nums=[10,9,2,5,3,7,101,18],算法过程如下所示:

    [result = [10] \ result = [9] gets 9 < 10 \ result = [2] gets 2 < 9 \ result = [2, 5] gets 5 > 2 \ result = [2, 3] gets 3 < 5 \ result = [2, 3, 7] gets 7 > 3 \ result = [2, 3, 7, 101] gets 101 > 7 \ result = [2, 3, 7, 18] gets 18 < 101 \ ]

    class Solution:
        def binary_search(self, result, data):
            n = len(result)
            i, j = 0, n-1
            while i <= j:
                mid = i + (j - i) // 2
                if result[mid] >= data:
                    if mid == 0 or result[mid-1] < data:
                        return mid
                    else:
                        j = mid - 1
                else:
                    i = mid + 1
            return -1
    
    
        def lengthOfLIS(self, nums: List[int]) -> int:
    
            n = len(nums)
            if n == 0:  return 0
            result = [nums[0]]
            for i in range(1, n):
                if nums[i] > result[-1]:
                    result.append(nums[i])
                elif nums[i] < result[-1]:
                    #在result中找到第一个大于等于nums[i]的元素位置
                    pos = self.binary_search(result, nums[i])
                    result[pos] = nums[i]
    
            return len(result)
    

    循环需要 (n) 次,二分查找复杂度为 (O(logn)),所以总体代码的时间复杂度为 (O(nlogn))

    获取更多精彩,请关注「seniusen」!

  • 相关阅读:
    Javascript
    CSS3新增特性HTML标签类型
    HTML5新增的标签
    prototype __proto__ Function
    oninput
    extend
    hasOwnProperty()
    this prototype constructor
    Array类型判断
    指针
  • 原文地址:https://www.cnblogs.com/seniusen/p/11991108.html
Copyright © 2011-2022 走看看