跳转至

LC300 - 最长递增子序列

LongestIncreasingSubsequence.go
package DP

import "math"

// lengthOfLIS: 求最长递增子序列长度
// 时间复杂度: O(n * log n), 空间复杂度: O(n) <最优解>
func lengthOfLIS(nums []int) int {
    size := len(nums)
    dp := make([]int, size)
    // dp[i]: 以i位置作为结尾的最长递增子序列长度
    ends := make([]int, 0)
    // ends[i]:长度为i+1的递增子序列的最小结尾
    ans := math.MinInt
    for i := 0; i < size; i++ {
        pos := find(ends, nums[i])
        if pos == len(ends) {
            ends = append(ends, nums[i])
        } else {
            ends[pos] = nums[i]
        }
        dp[i] = pos + 1
        ans = max(ans, dp[i])
    }
    return ans
}

// find: 在递增序列中找大于等于target的最左位置,不存在则返回size
func find(arr []int, target int) int {
    ans := len(arr)
    for left, right := 0, ans-1; left <= right; {
        mid := left + (right-left)/2
        if arr[mid] >= target {
            ans = mid
            right = mid - 1
        } else {
            left = mid + 1
        }
    }
    return ans
}

具体分析过程参加左神算法讲解