【代码随想录二刷】Day43-动态规划-Go

代码随想录二刷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]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值