300. 最长上升子序列
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
动态规划
func lengthOfLIS(nums []int) int {
if len(nums) == 0 {
return 0
}
ans:=1
maxLen := []int{1}
for i := 1; i < len(nums); i++ {
maxLenSoFar := 0
for j := 0; j < i; j++ {
if nums[i] > nums[j] {
maxLenSoFar = max(maxLen[j], maxLenSoFar)
}
}
ans=max(ans,maxLenSoFar+1)
maxLen = append(maxLen, maxLenSoFar+1)
}
return ans
}
func max(i, j int) int {
if i > j {
return i
} else {
return j
}
}
贪心算法+二分查找
思路简单,但是写出来就很麻烦,调边界头都大了。
func lengthOfLIS(nums []int) int {
if len(nums)<=1{
return len(nums)
}
minNums := []int{nums[0]}
mlen := 0
for i := 1; i < len(nums); i++ {
if nums[i] > minNums[mlen] {
minNums = append(minNums, nums[i])
mlen++
} else {
left, right := 0, len(minNums)-1
mid := (left + right) / 2
for left < right {
if nums[i] > minNums[mid] {
left = mid+1
} else if nums[i] < minNums[mid] {
right = mid
} else {
right=mid
break
}
mid = (left + right) / 2
}
minNums[right]=nums[i]
}
}
return len(minNums)
}