LeetCode300:Longest Increasing Subsequence

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.

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


LeetCode:链接

第一种方法:动态规划(Dynamic Programming),时间复杂度O(n^2)

状态转移方程:dp[x] = max(dp[x], dp[y] + 1) 其中 y < x 并且 nums[x] > nums[y]

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)
        dp = [1] * length
        for i in range(length):
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i], dp[j]+1)
        return max(dp) if dp else 0

第二种方法:二分法,时间复杂度O(n * log n)

思路是,我们先建立一个数组 ends,把首元素放进去,然后比较之后的元素。

  • 如果遍历到的新元素比ends数组中的首元素小的话,替换首元素为此新元素,
  • 如果遍历到的新元素比ends数组中的末尾元素还大的话,将此新元素添加到ends数组末尾(注意不覆盖原末尾元素)。
  • 如果遍历到的新元素比ends数组首元素大,比尾元素小时,此时用二分查找法找到第一个不小于此新元素的位置,覆盖掉位置的原来的数字,

以此类推直至遍历完整个 nums 数组,此时 ends 数组的长度就是我们要求的 LIS 的长度,特别注意的是 ends 数组的值可能不是一个真实的LIS,比如若输入数组nums为 {4, 2, 4, 5, 3, 7},那么算完后的ends数组为{2, 3, 5, 7},可以发现它不是一个原数组的LIS,只是长度相等而已,千万要注意这点

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if n == 0:
            return 0
        number = [nums[0]]
        for i in range(1, n):
            if nums[i] < number[0]:
                number[0] = nums[i]
            elif nums[i] > number[-1]:
                number.append(nums[i])
            else:
                low = 0
                high = len(number) - 1
                while low <= high:
                    mid = (low + high) // 2
                    if nums[i] > number[mid]:
                        low = mid + 1
                    else:
                        high = mid - 1
                number[low] = nums[i]
        return len(number)

猜你喜欢

转载自blog.csdn.net/mengmengdajuanjuan/article/details/84998065