首页 > 其他分享 >代码随想录day 38 || 322 零钱兑换,279 完全平方数,139 单词拆分

代码随想录day 38 || 322 零钱兑换,279 完全平方数,139 单词拆分

时间:2024-08-23 12:04:06浏览次数:7  
标签:38 return int 随想录 322 amount 背包 物品 dp

322 零钱找还

func coinChange(coins []int, amount int) int {
	// 装满,并且硬币无限,可以类比完全背包问题
	// dp[i][j] 表示前i个物品装满容量为j的背包所需要的最少物品数量
	// 递推公式 dp[i][j] = min(dp[i-1][j], dp[i][j-w(i)]+1) // 不装物品i的物品数量,装物品i的物品数量
	// 初始化 dp[0][0] = 0, 其他数值为math.minint
	// 遍历顺序,本题没有要求全排列或者全组合,所以用了二维,二维顺序是无所谓的,但是习惯还是先物品后背包
	// print
	var dp = make([][]int, len(coins) + 1)
	for idx, _ := range dp {
		dp[idx] = make([]int, amount + 1)
		for j := range dp[idx] {
			dp[idx][j] = amount + 1 // 用来表示一个无法凑成的最大金额,方便在min操作时取到正确的最小值
		}
	}
	dp[0][0] = 0
	for i:=0; i<len(coins); i++{
		for j:=0; j<=amount; j++{
			if j-coins[i] >= 0 { // 要满足剩余背包容量大于等于0
				dp[i+1][j] = min(dp[i][j], dp[i+1][j-coins[i]]+1)
			}else {
				dp[i+1][j] = dp[i][j]
			}
		}
	}

	//fmt.Println(dp)
	if dp[len(coins)][amount] > amount {
		return -1
	}
	return dp[len(coins)][amount]
}

func min(x,y int )int {
	if x < y{
		return x
	}
	return y
}

// 本题思路好找,难点在于取最小值的时候是否能够想到将dp数组初始化为一个比较大的数,而不是0
func coinChange(coins []int, amount int) int {
	// 装满,并且硬币无限,可以类比完全背包问题
	// dp[j] 表示装满容量为j的背包所需要的最少物品数量
	// 递推公式 dp[j] = min(dp[j], dp[j-w(i)]+1) // 不装物品i的物品数量,装物品i的物品数量
	// 初始化 dp[0] = 0, 其他数值为amount + 1, 这里表示如果全是1来组成amount,需要amount个1,这已经时需要的最大数量,那我设置amount+1,就是要比最大值还要大
	// 遍历顺序,本题没有要求全排列或者全组合,完全背包一位数组按照习惯先正序物品,后正序背包
	// print
	var dp = make([]int, amount + 1)
	for i, _ := range dp {
		dp[i] = amount + 1
	}
	dp[0] = 0
	for i:=0; i<len(coins); i++{
		for j:=0; j<=amount; j++{
			if j-coins[i] >= 0 { // 要满足剩余背包容量大于等于0
				dp[j] = min(dp[j], dp[j-coins[i]]+1)
			}
		}
	}

	//fmt.Println(dp)
	if dp[amount] > amount {
		return -1
	}
	return dp[amount]
}

func min(x,y int )int {
	if x < y{
		return x
	}
	return y
}

279 完全平方数

func numSquares(n int) int {
	// 完全背包
	// dp[j] 表示装满容量j的背包需要最少完全平方数
	// 递推 dp[j] = min(dp[j], dp[j-i^2] + 1)
	// dp[0] = 0  其他初始化成为n+1
	// 先正序物品,后正序背包 背包0->n 物品0->n开方+1
	// print

	var dp = make([]int, n+1)
	s := int(math.Sqrt(float64(n))) + 1
	for idx, _ := range dp {
		dp[idx] = n+1
	}
	dp[0] = 0
	for i:=1; i<=s; i++ {
		for j:=i*i; j<=n; j++{
			dp[j] = min(dp[j], dp[j-i*i]+1)
		}
	}
	fmt.Println(dp)
	return dp[n]
}

139 单词拆分

func wordBreak(s string, wordDict []string) bool {
	// 本题可以联想到完全背包问题,但是难点在于,1 dp数组含义 2 递推公式 3 遍历顺序
	// dp[j] 表示前j个字母能够呗字典中的单词拼出
	// 递推公式,对于每一个单词  dp[j] = dp[j-len()] && true  表示本单词+目标-本单词长度剩余的单词能否被拼出
	// 遍历顺序,字典可能被多次使用,并且顺序可以颠倒,所以时全排列,先正序背包,后正序物品
	// print

	m := minlength(wordDict)
	if len(s) < m {
		return false
	}
	var dp = make([]bool, len(s) + 1)
	dp[0] = true
	for j:=m-1; j<len(s); j++ {
		for i:=0; i<len(wordDict); i++{
			diff := j-len(wordDict[i])+1
			if diff >= 0 && s[diff: j+1] == wordDict[i]{
				dp[j+1] = dp[diff]
			}
			if dp[j+1] == true {
				break
			}
		}
	}

	//fmt.Println(dp)
	return dp[len(s)]
}

func minlength(dict []string) int {
	var m int = math.MaxInt
	for _, v := range dict{
		if len(v) < m {
			m = len(v)
		}
	}
	return m
}

标签:38,return,int,随想录,322,amount,背包,物品,dp
From: https://www.cnblogs.com/zhougongjin55/p/18375740

相关文章

  • 代码随想录DAY22 - 回溯算法 - 08/21
    目录理论回顾什么是回溯法回溯法的效率回溯法解决的问题如何理解回溯组合题干思路和代码递归法递归优化:剪枝组合总和Ⅲ题干思路和代码递归法递归优化电话号码的字母组合题干思路和代码递归法理论回顾什么是回溯法回溯是一种类似枚举的搜索方法,回溯和......
  • 代码随想录DAY23 - 回溯算法 - 08/22
    组合总和题干题目:给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。candidates中的同一个数字可以无限制重复被选取。如果至少......
  • 代码随想录算法训练营第二十三天(回溯 二)
    力扣题部分:39.组合总和题目链接:.-力扣(LeetCode)题面:给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。candid......
  • 代码随想录算法训练营第二十二天(回溯 一)
    开始学习回溯!回溯理论基础代码随想录文章链接:代码随想录文章摘要:什么是回溯法回溯法也可以叫做回溯搜索法,它是一种搜索的方式。在二叉树系列中,我们已经不止一次,提到了回溯。回溯是递归的副产品,只要有递归就会有回溯。所以以下讲解中,回溯函数也就是递归函数,指的都是一......
  • 代码随想录Day23
    131.分割回文串给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。示例1:输入:s="aab"输出:[["a","a","b"],["aa","b"]]示例2:输入:s="a"输出:[["a"]]提示:1<=s.length<=16s仅由......
  • 「代码随想录算法训练营」第四十四天 | 图论 part2
    200.岛屿数量题目链接:https://leetcode.cn/problems/number-of-islands/description/文章讲解:https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html题目难度:中等题目状态:看题解思路一:深搜版方法dfs:参数:接受一个字符网格grid和当前坐标(r,c)。功能:......
  • 给自己复盘的随想录笔记-移除元素
    双指针法双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。定义快慢指针快指针:寻找新数组的元素,新数组就是不含有目标元素的数组慢指针:指向更新新数组下标的位置相关题目删除有序数组中的重复项解题思路:解法:双指针首先注意数组......
  • 给自己复盘用的随想录笔记day1-二分查找
    二分法使用情景数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。求某一个整数的平方根边界条件写二分法......
  • 代码随想录 -- 数组 -- 螺旋矩阵II
    59.螺旋矩阵II-力扣(LeetCode)每画一条边都要坚持一致的左闭右开注意处理n为奇数时的矩阵中心点classSolution(object):defgenerateMatrix(self,n):res=[[0]*nforainrange(n)]startX=0startY=0loop=mid=n/2c......
  • 代码随想录 -- 数组 -- 区间和
    58.区间和(第九期模拟笔试)(kamacoder.com)暴力解法大概率超时,应采用前缀和解法p[i] 表示vec[0]到vec[i]的累加和求vec[m] 到vec[n] 的和只需要 p[n]-p[m] 即可知识点input函数Python3 中raw_input()和input()进行了整合,去除了raw_input(),仅保留了i......