代码随想录算法训练营之JAVA|第三十六天|343. 整数拆分

文章讲述了作者在刷LeetCode第416题时,起初使用回溯法超时,后来通过观看代码随想录理解了如何运用0-1背包的动态规划方法解决问题。作者强调了模板和模式的重要性,以及如何将题目转化为0-1背包问题求解思路。
摘要由CSDN通过智能技术生成

今天是第36天刷leetcode,立个flag,打卡60天。

算法挑战链接

416. 分割等和子集icon-default.png?t=N6B9https://leetcode.cn/problems/partition-equal-subset-sum/

第一想法

题目理解:将一个数组分成两份,让两份之和相等。

这种题目下意识会使用回溯,因为尝试所有的结果是可以知道答案的。

但是回溯的代码会导致超时。

于是我就做不出来了。~~~~~~~

看完代码随想录之后的想法 

代码随想录使用的是0-1背包的方式来解决这个问题的。(但是为什么用0-1背包呢?我没有想清楚。)

题目中给到的数组可以当成是物品,背包的容量是j。

题目的意思是:物品任取的情况下,是否可以恰好装满某个容量的背包。

因此可以套上0-1背包的公式去解决。

动态规划的五部曲走起:

  • 确定dp数组(dp table)以及下标的含义

dp[j] 代表的含义是:在 0-i 物品任取的情况下,容量为 J 的最大价值 

  • 确定递推公式

递推公式就直接写了,因为是0-1背包的公式 dp[j] = max(dp[j], dp[j-i] + nums[i])

  • dp的初始化

需要将dp数组全部初始化为0

  • 确定遍历顺序

先遍历物品,然后在遍历容量,遍历容量的时候需要从大到小开始遍历,因为有每个物品只能使用一次的限制。

  • 举例推导dp数组

数据就不推导了。

代码如下:

class Solution {
    public boolean canPartition(int[] nums) {
        if (nums.length <= 1) {
            return false;
        }

        //计算总数
        int sum = 0;
        for (int num : nums) {
            sum+=num;
        }

        //如果总数是奇数,不能平分
        if (sum % 2 != 0) {
            return false;
        }

        //dp[j] 表示在容量为j的情况下,价值最大
        int medium = sum / 2;
        int dp[] = new int[medium+1];

        for (int i = 0; i < nums.length; i++) {
            for (int j = medium; j >= nums[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]);
            }

        }
        return dp[medium] == medium;
    }
}

实现过程中遇到哪些困难 

不知道为啥可以使用0-1背包来解决这个问题(在没有做出来的时候)

今日收获

模版很重要,省事

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值