代码随想录二刷Day43
今日任务
1049.最后一块石头的重量 II
494.目标和
474.一和零
语言:Go
1049.最后一块石头的重量 II
链接:https://leetcode.cn/problems/last-stone-weight-ii/
二维数组
func max(i, j int) int {
if i < j {
return j
} else {
return i
}
}
func lastStoneWeightII(stones []int) int {
//1.dp数组及下标含义: dp[i][j]表示从0-i的下标中取石头,容量为j的背包最多可以背的重量为dp[i][j]
//2.dp递归公式
//3.初始化dp
//4.dp遍历顺序
//5.举例推导验证
sum := 0
for i := 0; i < len(stones); i++ {
sum += stones[i]
}
target := sum / 2
dp := make([][]int, len(stones))
for i := 0; i < len(stones); i++ {
dp[i] = make([]int, target + 1)
}
for j := stones[0]; j <= target; j++{
dp[0][j] = stones[0]
}
for i := 1; i < len(stones); i++ {
for j := 1; j <= target; j++ {
//dp递推公式,分情况讨论
if j < stones[i] {
dp[i][j] = dp[i - 1][j]
} else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - stones[i]] + stones[i])
}
}
}
return (sum - dp[len(stones) - 1][target]) - dp[len(stones) - 1][target]
}
一维数组
func max(i, j int) int {
if i < j {
return j
} else {
return i
}
}
func lastStoneWeightII(stones []int) int {
//1.dp数组及下标含义: dp[j]表示容量为j的背包最多可以背的重量为dp[j]
//2.dp递归公式: dp[j] = max(dp[j - stones[i]] + stones[i], dp[j])
//3.初始化dp
//4.dp遍历顺序
//5.举例推导验证
sum := 0
for i := 0; i < len(stones); i++ {
sum += stones[i]
}
target := sum / 2
dp := make([]int, target + 1)
for j := stones[0]; j <= target; j++{
dp[j] = stones[0]
}
for i := 1; i < len(stones); i++ {
for j := target; j >= stones[i]; j-- {
dp[j] = max(dp[j - stones[i]] + stones[i], dp[j])
}
}
return (sum - dp[target]) - dp[target]
}
494.目标和
链接:https://leetcode.cn/problems/target-sum/
二维数组,官方解答的解析更明确些
func findTargetSumWays(nums []int, target int) int {
sum := 0
for i := 0; i < len(nums); i++ {
sum += nums[i]
}
find := (sum + target) / 2
if int(math.Abs(float64(target))) > sum {
return 0
}
if (sum + target) % 2 == 1 {
return 0
}
//dp[i][j]表示从数组的前i个数中任取,组成表达式结果为j的方式共有dp[i][j]种
//对每个元素:取或不取
dp := make([][]int, len(nums) + 1)
for i := 0; i <= len(nums); i++ {
dp[i] = make([]int, find + 1)
}
dp[0][0] = 1
for i := 0; i < len(nums); i++ {
for j := 0; j <= find; j++ {
if j < nums[i] {
dp[i + 1][j] = dp[i][j] //从前i+1个数字中取,第i+1个数字对应的是nums[i]
} else {
dp[i + 1][j] = dp[i][j - nums[i]] + dp[i][j]
}
}
}
return dp[len(nums)][find]
}
一维数组
func findTargetSumWays(nums []int, target int) int {
sum := 0
for i := 0; i < len(nums); i++ {
sum += nums[i]
}
find := (sum + target) / 2
if int(math.Abs(float64(target))) > sum {
return 0
}
if (sum + target) % 2 == 1 {
return 0
}
//dp[j]表示组成表达式结果为j的方式共有dp[j]种
//对每个元素:取或不取
dp := make([]int, find + 1)
dp[0] = 1
for i := 0; i < len(nums); i++ {
for j := find; j >= nums[i]; j-- {
dp[j] += dp[j - nums[i]]
}
}
return dp[find]
}
474.一和零
链接:https://leetcode.cn/problems/ones-and-zeroes/
三维数组:官方题解
func max(i, j int) int {
if i < j {
return j
} else {
return i
}
}
func findMaxForm(strs []string, m int, n int) int {
//dp[k][i][j]表示在前k个字符串中,使用i个0和j个1可以得到的字符串数量最多为dp[k][i][j]
dp := make([][][]int, len(strs) + 1)
for k := 0; k <= len(strs); k++ {
dp[k] = make([][]int, m + 1)
for i := 0; i <= m; i++ {
dp[k][i] = make([]int, n + 1)
}
}
for k := 0; k < len(strs); k++ {
zero := strings.Count(strs[k], "0")
one := len(strs[k]) - zero
for i := 0; i <= m; i++ {
for j := 0; j <= n; j++ {
if i < zero || j < one {
dp[k + 1][i][j] = dp[k][i][j]
} else {
dp[k + 1][i][j] = max(dp[k][i][j], dp[k][i - zero][j - one] + 1)
}
}
}
}
return dp[len(strs)][m][n]
}
二维数组
func max(i, j int) int {
if i < j {
return j
} else {
return i
}
}
func findMaxForm(strs []string, m int, n int) int {
//dp[i][j]表示使用i个0和j个1可以得到的字符串数量最多为dp[i][j]
dp := make([][]int, m + 1)
for i := 0; i <= m; i++ {
dp[i] = make([]int, n + 1)
}
for k := 0; k < len(strs); k++ {
zero := strings.Count(strs[k], "0")
one := len(strs[k]) - zero
for i := m; i >= zero; i-- {
for j := n; j >= one; j-- {
dp[i][j] = max(dp[i][j], dp[i - zero][j - one] + 1)
}
}
}
return dp[m][n]
}