300. 最长上升子序列 Golang 动态规划 贪心算法+二分查找

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)
}
发布了38 篇原创文章 · 获赞 0 · 访问量 1028

猜你喜欢

转载自blog.csdn.net/Cyan1956/article/details/104858686