最长递归子序列——动态规划

92 阅读1分钟

image.png

方法

  1. ans维护当前最长子序列长度
  2. dp维护当前各个长度子序列的最大值(如长度为1的最大值,为2,为3的,一直到长度为ans的)
  3. 外层for遍历
  4. 如果dp[ans] > nums[i]那么我们要考虑当前的nums[i]是否比我们dp数组中某个长度的最大值还要小,所以我们需要内层for更新我们的dp数组
  5. 内层for用来更新某个长度子序列的最大值,这里的某个长度需要(ans--)倒着来,因为例如我们更新了长度为3的最大值,我们自然不需要更新长度为2的,因为3的最大值是要满足大于2的最大值的且小于4的最大值的,再往下遍历是没有意义的
  6. 如果dp[ans] < nums[i]那么便直接更新ans状态和dp数组状态
  7. dp[ans] = nums[i]这种情况是没有意义的,因为它无法让我们更新ans和ap数组中的任意一个值

如题示例1: dp[1]=10——>dp[1]=9——>dp[1]=2——>dp[1]=2,dp[2]=5——>dp[1]=2,dp[2]=3——>dp[1]=2,dp[2]=3,dp[3]=7。。。以此类推

func lengthOfLIS(nums []int) int {
    ans := 1
    dp := make([]int,len(nums)+1)
    dp[1] = nums[0]
    for i := 1; i < len(nums); i++ {
       if dp[ans] > nums[i] {
           for a := ans; a > 0; a-- {
                if dp[a-1] < nums[i] {
                    dp[a] = nums[i]
                    break
                }
                if a == 1 {
                    dp[a] = nums[i]
                }
           }
       }else if dp[ans] < nums[i] {
           ans++
           dp[ans] = nums[i]
       }
    }
    return ans
}