LeetCode-Python-300. 最长上升子序列

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

示例:

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

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

第一种思路:

用dp[i] 表示 从下标0 到下标i 的最长上升子序列的长度,

例如对于样例输入[10,9,2,5,3,7,101,18], 有 dp = [ 1, 1, 1, 2, 2, 3, 4, 4]。

显然dp[0] = 1

对于任意的i 不为零的情况,应该在 i 的左侧找一个下标 j ,其满足两个条件:

1. nums[ j ]比 nums[ i ] 小

2. 它是所有满足条件1里 dp [j]  最大的那个

dp[i] = max(dp[j]) + 1 , j < i and nums[ j ] < nums[ i ]

如果不存在这样的下标j,说明在0 ~ i - 1 的范围内,所有元素都比nums[i] 大,即无法找到一个能和 nums[i] 组成上升子序列的元素,所以dp[i] = 1, 表示为nums[i] 自身成为一个长度为1 的上升子序列。

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l = len(nums)
        if not l:
            return 0
        dp = [1 for _ in range(l)]
        
        for index, item in enumerate(nums):
            dp[index] = self.find(nums[:index + 1], dp) + 1
        # print dp       
        return max(dp)
            
    
    def find(self, nums, dp):
        max_element = -1 * 2 << 31
        
        for i in range(len(nums) - 2, -1, -1):
            if nums[i] < nums[-1]:
                max_element = max(max_element, dp[i]) 

        return max_element if max_element != -1 * 2 << 31 else 0

#修改前的在下面:
class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l = len(nums)
        if not l:
            return 0
        dp = [0 for _ in range(l)]
        
        for index, item in enumerate(nums):
            if index == 0:
                dp[index] = 1
            else:
                val = self.findClosestSmallerElementInLeft(nums[:index + 1], dp)
                if val == -1:
                    dp[index] = 1
                else:
                    dp[index] = val + 1
        print dp       
        return max(dp)
            
    
    def findClosestSmallerElementInLeft(self, nums, dp):
        max_element = -1 * 2 << 31
        for i in range(len(nums) - 2, -1, -1):
            if nums[i] < nums[-1]:
                max_element = max(max_element, dp[i]) 
        # print nums[-1], max_element
        return max_element if max_element != -1 * 2 << 31 else -1

第二种思路:

从评论区学来的,思路差不多,但是实现会更加简洁。

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

猜你喜欢

转载自blog.csdn.net/qq_32424059/article/details/88076376