LeetCode 300. 最长递增子序列
题目链接:300. 最长递增子序列
思路:使用动态规划的思想。
- 确定dp数组及其下标的含义
dp[i]代表结尾为nums[i]时的最长递增子序列的长度 - 确定递推公式
首先要满足递增,nums[i] 要大于 nums[j](i > j),再之后遍历dp[i]和每一个dp[j]+1,如果有更大者就替换原来的dp[i]。 - dp数组初始化
全部初始化为1即可。 - 确定遍历顺序
找子序列,从前往后遍历即可。 - 打印结果
这里有一个细节,不应该像某些动规题目那样打印dp数组的最后一位,而是应该时刻记录过程中遇到的最大值,最后返回这个最大值。因为数组递增子序列最大的元素不一定是数组最末尾的元素。
go版本:
func lengthOfLIS(nums []int) int {
dp := make([]int, len(nums))
for i:=0; i<len(nums); i++ {
dp[i] = 1
}
res := 1
for i:=0; i<len(nums); i++ {
for j:=0; j<i; j++ {
if nums[i] > nums[j] {
dp[i] = max(dp[i], dp[j]+1)
}
if dp[i]>res {
res = dp[i]
}
}
}
return res
}
func max(i, j int) int {
if i > j {
return i
} else {
return j
}
}
LeetCode 674. 最长连续递增序列
题目链接:674. 最长连续递增序列
思路:与上一题思路一致,只不过比上一题要简单一些,因为要判断的是最长连续递增序列,所以不需要进行两层循环,而只需要一层循环,每次跟自己的前者比较大小即可。大于前者就在前者基础上+1,小于等于的话就置为1。
go版本:
func findLengthOfLCIS(nums []int) int {
res := 1
dp := make([]int, len(nums))
dp[0] = 1
for i:=1; i<len(nums); i++ {
if nums[i]>nums[i-1] {
dp[i] = dp[i-1]+1
} else {
dp[i] = 1
}
if dp[i] > res {
res = dp[i]
}
}
return res
}
LeetCode 718. 最长重复子数组
题目链接:718. 最长重复子数组
思路:使用动态规划的思想。
- 确定dp数组及其下标的含义
这道题涉及两个数组,所以需要使用一个二维的dp数组来储存信息。
dp[i][j]代表结尾为nums1[i]和结尾为nums2[j]的最长重复子数组的个数。 - 确定递推公式
当nums[i - 1] 和nums[j - 1]相等的时候, d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j] = dp[i - 1][j - 1] + 1 dp[i][j]=dp[i−1][j−1]+1 - dp数组初始化
全部初始化为0即可。 - 确定遍历顺序
从前往后遍历即可。 - 打印结果
记录过程中遇到的最大值,最后返回这个最大值。
go版本:
func findLength(nums1 []int, nums2 []int) int {
l1 := len(nums1)
l2 := len(nums2)
dp := make([][]int, l1+1)
res := 0
for i:=0; i<=l1; i++ {
dp[i] = make([]int, l2+1)
}
for i:=1; i<=l1; i++ {
for j:=1; j<=l2; j++ {
if nums1[i-1]==nums2[j-1] {
dp[i][j] = dp[i-1][j-1]+1
}
if res < dp[i][j] {
res = dp[i][j]
}
}
}
return res
}