[leetcode] 300. Longest Increasing Subsequence @ python

原题

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?

解法1

动态规划. 构造数组dp, dp[i]表示到i点时能构成的递增数组的长度, 初始化dp为值为1的数组, 状态转移方程为:

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

遍历nums, 对每个数字, 寻找它之前比它小的数字, 这样能构成递增数组, 更新dp[i], 最后返回数组dp的最大值即可.
Time: O(n**2)
Space: O(n)

代码

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

解法2

二分搜索法. 构造sub, 表示当前的递增数列, 遍历nums, 找到如果n插入sub时, 它应该处在的位置. 如果pos == len(sub)表示n比sub里所有数都大, 直接加到sub中, 其他情况表示n<= sub[pos], 更新sub[pos]. 最后返回sub的长度即可.

代码

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        def binarySearch(sub, n):
            # return the index of n for insertion
            left, right = 0, len(sub)-1
            while left <= right:
                mid = (left+right)//2
                if n == sub[mid]:
                    return mid
                elif n > sub[mid]:
                    left = mid+1
                else:
                    right = mid-1
                    
            return left
        
        sub = []
        for n in nums:
            pos = binarySearch(sub, n)
            if pos == len(sub):
                sub.append(n)
            else:
                sub[pos] = n
                
        return len(sub)

解法3

二分搜索法, 同解法2, 使用bisect.bisect_left()方法

代码

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """        
        sub = []
        for n in nums:
            pos = bisect.bisect_left(sub, n)
            if pos == len(sub):
                sub.append(n)
            else:
                sub[pos] = n
                
        return len(sub)

你可能感兴趣的:(Leetcode)