剑指Offer专项突击版题解十一

101.分割等和子集

思路:面对一堆数字喝一个目标值的时候,有以下几种情况,数字中是否包含重复数字,数字中的数是否可以被重复选择。这种需要进行分类讨论。

这个题目是属于:不能重复选择的类型,那就按照0-1背包的写法,写成二维数组dp[i][j]表示前0-i的下标能否组成目标值j,nums放在外层,如果写一维的话,需要注意在两层写法的时候不一样。

func canPartition(nums []int) bool {
    n := len(nums)
    if n < 2 {
        return false
    }
    sum, max := 0, 0
    for _, v := range nums {
        sum += v
        if v > max {
            max = v
        }
    }
    if sum%2 != 0 {
        return false
    }

    target := sum / 2
    if max > target {
        return false
    }

    dp := make([][]bool, n)
    for i := range dp {
        dp[i] = make([]bool, target+1)
    }
    for i := 0; i < n; i++ {
        dp[i][0] = true
    }
    dp[0][nums[0]] = true
    for i := 1; i < n; i++ {
        v := nums[i]
        for j := 1; j <= target; j++ {
            if j >= v {
                dp[i][j] = dp[i-1][j] || dp[i-1][j-v]
            } else {
                dp[i][j] = dp[i-1][j]
            }
        }
    }
    // fmt.Println(dp)
    return dp[n-1][target]
}

 102.加减的目标值

思路:dfs

103.最少的硬币数目

思路:这是典型的课重复选择的问题,硬币数可以重复选择,可重复选的可以用一维。 

104.排列的数目

思路:这里典型的是可以重复选的类型,nums放在里面。

func combinationSum4(nums []int, target int) int {
	dp := make([]int, target+1)
	dp[0] = 1
	for i := 1; i <= target; i++ {
		for j := 0; j < len(nums); j++ {
			if i >= nums[j] {
				dp[i] += dp[i-nums[j]]
			}
		}
	}
	return dp[target]
}

105.岛屿的最大面积

dfs,在涉及岛屿的时候,在遍历结束后可以淹没岛屿表示已经遍历了。

106.二分图

dfs或者bfs

107.矩阵中的距离

bfs

108.单词演变

双向bfs,双向bfs的核心每次都会选择集合小的那头进行遍历,能很大的减少遍历数。

109.开密码锁

bfs

110.所有路径

dfs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿联爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值