最长上升子序列
题目描述
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
思路
思路一:
维护ans数组,ans[i]表示以nums[i]结尾的数组的最长上升子序列长度。时间复杂度n2
更新ans时,ans[i]=max(ans[j])+1 {其中0≤j<i,且nums[i]>nums[j]}
code
func lengthOfLIS(nums []int) int {
ans := make([]int, len(nums))
res := 0
for k, v := range nums {
cnt := 0
for j := k - 1; j >= 0; j-- {
if v > nums[j] {
cnt = max(cnt, ans[j])
}
}
ans[k] = cnt + 1
res = max(res, ans[k])
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
思路二:
维护ans数组,ans[i]表示长度为i的最长上升子序列的最小结尾数。可以保证ans数组是单调递增的。时间复杂度nlgn
对于nums[i],二分查找ans中大于等于nums[i]的位置,更新ans,最终结果为ans数组长度。
code
func lengthOfLIS(nums []int) int {
ans := make([]int, 0)
for _, v := range nums {
pos := bs(ans, v)
if pos > len(ans)-1 {
ans = append(ans, 0)
}
ans[pos] = v
}
return len(ans)
}
func bs(nums []int, val int) int {
l, r := 0, len(nums)
for l < r {
m := (r-l)/2 + l
if nums[m] < val {
l = m + 1
} else {
r = m
}
}
return l
}