0300 Longest Increaseing Subsequence

0300 Longest Increaseing Subsequence#

Given an integer array nums, return the length of the longest strictly increasing subsequence.

Example 1:

Input: nums = [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.
Example 2:

Input: nums = [0,1,0,3,2,3]
Output: 4
Example 3:

Input: nums = [7,7,7,7,7,7,7]
Output: 1
 
Constraints:

1 <= nums.length <= 2500
-104 <= nums[i] <= 104

Follow up: Can you come up with an algorithm that runs in O(n log(n)) time complexity?

  • Dynamic programming solves this problem in \(O(n^2)\)

  • Binary search can be used here to perform \(O(n^2)\) operations.

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


# test on typical cases
print(lengthOfLIS([10,9,2,5,3,7,101,18]))
print(lengthOfLIS([1,3,6,7,9,4,10,5,6]))
print(lengthOfLIS([1,2,3,4,5,6,7,8,9]))
print(lengthOfLIS([9,8,7,6,5,4,3,2,1]))
print(lengthOfLIS([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]))
4
6
9
1
9
# use binary search within patience sort
def lengthOfLIS(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    if not nums:
        return 0
    # top of each pile in the patience sort
    # dp is sorted in ascending order
    dp = [nums[0]]
    for i in range(1, len(nums)):
        if nums[i] > dp[-1]:
            dp.append(nums[i])
        else:
            # binary search to find the leftmost element (smallest) in piles that is larger than nums[i]
            l, r = 0, len(dp)-1
            while l <= r:
                mid = (l+r)//2
                # move right
                if dp[mid] < nums[i]:
                    l = mid + 1
                # move left
                else:
                    r = mid - 1
            dp[l] = nums[i]
    return len(dp)

# test
print(lengthOfLIS([10,9,2,5,3,7,101,18]))
print(lengthOfLIS([1,3,6,7,9,4,10,5,6]))
print(lengthOfLIS([1,2,3,4,5,6,7,8,9]))
print(lengthOfLIS([9,8,7,6,5,4,3,2,1]))
print(lengthOfLIS([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]))
4
6
9
1
9