动态规划习题(二)

leetcode 300. 最长上升子序列

  • O(N^2)解法,动态规划
func lengthOfLIS(nums []int) int {
	n := len(nums)
	if n == 0 {
		return 0
	}
	ret := 1
	dp := make([]int, n)
	dp[0] = 1
	// dp[i]表示,包括i这个数的数组,最大
	for i := 1; i < n; i++ {
		// 初始值都为1
		dp[i] = 1
		for j := 0; j < i; j++ {
			// 如果当前数字大于那个位置的数字,那么显然算上当前数字,序列会加1
			// 比那个位置小或者等于那个位置的情况,在之前或者之后的j得到处理(即和每个j都比较了)
			// dp[i] 取之前的所有dp[j]中的最大值加1
			if nums[i] > nums[j] {
				dp[i] = max(dp[i], dp[j]+1)
			}
		}
		ret = max(ret, dp[i])
	}
	return ret
}
  • O(NlogN),第二层循环用二分法替换
func lengthOfLIS(nums []int) int {
	n := len(nums)
	if n == 0 {
		return 0
	}
	// 维护最长子序列数组
	list := []int{nums[0]}
	var l, r, mid int
	for i := 1; i < n; i++ {
		l, r = 0, len(list)-1
		// 二分 注意是小于等于,因为还要判断最后一个数字
		for l <= r {
			mid = (l + r) / 2
			if list[mid] >= nums[i] {
				r -= 1
			}else {
                l += 1
            }
		}
		// 说明list中数字都小
		if mid == r {
			list = append(list, nums[i])
		} else { // 说明有比他大的,第一个就是mid
			list[mid] = nums[i]
		}
	}
	return len(list)
}

leetcode 322. 零钱兑换

func coinChange(coins []int, amount int) int {
    dp := make([]int,amount+1)
    dp[0] = 0
    for i:=1; i <= amount;i++{
        dp[i] = amount+1
        for j:=0;j<len(coins);j++{
            if coins[j]<=i{
                dp[i] = min(dp[i],dp[i-coins[j]]+1)
            }
        }
    }
    if dp[amount] > amount{
        return -1
    }
    return dp[amount]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值