算法训练 Day 52

LeetCode 300. 最长递增子序列

题目链接:300. 最长递增子序列

思路:使用动态规划的思想。

  1. 确定dp数组及其下标的含义
    dp[i]代表结尾为nums[i]时的最长递增子序列的长度
  2. 确定递推公式
    首先要满足递增,nums[i] 要大于 nums[j](i > j),再之后遍历dp[i]和每一个dp[j]+1,如果有更大者就替换原来的dp[i]。
  3. dp数组初始化
    全部初始化为1即可。
  4. 确定遍历顺序
    找子序列,从前往后遍历即可。
  5. 打印结果
    这里有一个细节,不应该像某些动规题目那样打印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. 最长重复子数组

思路:使用动态规划的思想。

  1. 确定dp数组及其下标的含义
    这道题涉及两个数组,所以需要使用一个二维的dp数组来储存信息。
    dp[i][j]代表结尾为nums1[i]和结尾为nums2[j]的最长重复子数组的个数。
  2. 确定递推公式
    当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[i1][j1]+1
  3. dp数组初始化
    全部初始化为0即可。
  4. 确定遍历顺序
    从前往后遍历即可。
  5. 打印结果
    记录过程中遇到的最大值,最后返回这个最大值。

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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值