题目:leetcode300.最长递增子序列
下面奉上我的代码,并向大家介绍下我的思路历程
// dp[i],以索引i为结尾的,最长递增 dp[i]需要由dp[0]到dp[i-1]组成
func lengthOfLIS(nums []int) int {
n := len(nums)
dp := make([]int, n)
for i := 0; i < n; i++ {
dp[i] = 1
}
for i := 1; i < n; i++ {
for j := 0; j < i; j++ {
if nums[i] > nums[j] {
if dp[j]+1 > dp[i] {
dp[i] = dp[j] + 1
}
}
}
}
max := 0
for i := 0; i < n; i++ {
if dp[i] > max {
max = dp[i]
}
}
return max
}
首先,刷过题的都知道应该用动态规划,但是时间一久,就忘记了套路,实际上还是理解不够深入。
看到这个题,首先我就在找递推关系,以序号i结尾的最长递增子序列到底该怎样以序号i-1为结尾的最长递增子序列得到呢?这时大家就入陷阱了!因为对于以序号i-1为结尾的最长递增子序列,我们并无法知道这个子序列的结尾是否为i-1,而且大概率不是的。那大家可能觉得就很难找到递推关系了。我们该怎么办呢?既然我们的关键是想知道的最长递增子序列是要以序号i-1为结尾,那不妨我们就直接设dp[i]为以i为结尾的最长递增子序列就好了!
这样的话,dp[i]该如何得来呢?我们需要从序号0遍历到i-1,如果nums[i] > nums[j],我们就比较dp[i]和dp[j]+1的关系,如果dp[j]+1更大,那我们就更新dp[i],这样最后找到的就是最大的dp[i]。
最后一个注意点,最大值一定是dp[n-1]吗,这时我们就思考dp[i]的含义,显然dp[i]是以序号i为结尾的最长递增子序列,所以我们需要从0遍历到n-1,取出最大的dp[i]!
大家怎么看呢?欢迎讨论!