给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
用dp的思想可以很简单得到递推式,dp[i] = dp[j] + 1(if nums[j] > dp[i]),不过这个算法复杂度是O(n2)的
func lengthOfLIS(nums []int) int {
// dp[i] = dp[j] + 1(if nums[j] > dp[i])
dp := make([]int, len(nums))
for i := 0; i < len(nums); i++ {
if dp[i] == 0 {
countdp(nums, i, dp)
}
}
maxnum := 0
for i := 0; i < len(dp); i++ {
if dp[i] > maxnum {
maxnum = dp[i]
}
}
return maxnum
}
func countdp(nums []int, index int, dp []int) {
ret := 1
for i := index+1; i < len(nums); i++ {
if nums[i] > nums[index] {
if dp[i] == 0 {
countdp(nums, i, dp)
}
if dp[i]+1 > ret {
ret = dp[i]+1
}
}
}
dp[index] = ret
}
O(nlogn)的解法实在是巧妙,使用了dp存放临时数组。把jth的数组值在dp内进行查找,做替换,不会增加dp的长度。只有最大值比边界大时才更新最长子序列长度。