码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode300:最长上升子序列LIS ====》动规

时间:2020-08-18 13:57:25      阅读:61      评论:0      收藏:0      [点我收藏+]

标签:while   inf   info   style   sel   元素   ++   arch   self   

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

示例:

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

可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

 

dp[i]表示以nums[i]结尾的最长上升子序列的长度

==》如果nums[i]比前面的所有元素都小,那么dp[i]等于1

==》如果nums[i]前面存在比他小的元素nums[j],nums[k]......,那么dp[i]就等于max(dp[j], dp[k]...)+1

======================================Python============================================

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp = [1 for _ in range(len(nums))]
        for i in range(len(nums)):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[j]+1, dp[i])
        return max(dp)
====================================================
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        res = float("-inf")
        dp = [1 for _ in range(len(nums))]
        for i in range(len(nums)):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[j]+1, dp[i])
            res = max(res, dp[i])
        return res

========================================Go=======================================

func lengthOfLIS(nums []int) int {
    if len(nums) < 1 {
            return 0
        }
        dp := make([]int, len(nums))
        res := 1
        for i := 0; i < len(nums); i++{
            dp[i] = 1
            for j:= 0; j < i; j++{
                if nums[j] < nums[i] {
                    dp[i] = max(dp[i], dp[j] + 1)
                }
            }
            res = max(res, dp[i])
        }
        return res
}
func max(a, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

========================================Java======================================

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int res = 0;
        for (int i = 0; i < nums.length; i++){
            dp[i] = 1;
            for (int j = 0; j < i; j++){
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}

 

技术图片

 

 

 

贪心+二分

如果要使上升子序列尽可能的长,则需要让序列上升得尽可能慢,因此希望每次在上升子序列最后加上的那个数尽可能的小。

技术图片

 

 技术图片

 

=============================================Python================================================

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        length = 1
        dp = [nums[0]]
        for i in range(1, len(nums)):
            if nums[i] > dp[length-1]:
                length += 1
                dp.append(nums[i])
            else:
                ind = self.binarySearch(nums[i], dp)
                dp[ind] = nums[i]
        return len(dp)

    def binarySearch(self, target, arr):
        if len(arr) == 0:
            return 0
        left = 0
        right = len(arr) - 1
        while left <= right:
            mid = left + ((right - left) >> 1)
            if arr[mid] < target:
                left = mid + 1
            else:
                if mid == 0 or arr[mid - 1] < target:
                    return mid
                else:
                    right = mid - 1
        return mid

 

leetcode300:最长上升子序列LIS ====》动规

标签:while   inf   info   style   sel   元素   ++   arch   self   

原文地址:https://www.cnblogs.com/liushoudong/p/13511954.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!