416. 分割等和子集

一、题目

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

二、思路

假定nums[]数组下标从1开始,如何确定f[i][j]的值?

我们一般去考虑最后一步,那么对于当前的数字 nums[i],可以选取也可以不选取:

  • 1、不选 nums[i],那么我们就从前i - 1个数中选,看是否使得这些数字的和恰好等于j,即 f[i][j] = f[i - 1][j]
  • 2、选择nums[i] ,在背包可以装下的情况下,那么相应的背包容量就要减去nums[i] ,f[i][j]的状态就可以从f[i - 1][j - nums[i]]转移过来,即f[i][j] = f[i - 1][j - nums[i]]

综上,两种情况只要有一个为truef[i][j]就为true。因此状态转移方程为f[i][j] = f[i - 1][j] | f[i - 1][j - nums[i]]

三、代码

复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        int n = nums.length, sum = 0;
        for(int x : nums) sum += x;
        if(sum % 2 != 0) return false;
        int m = sum / 2;
        boolean[][] f = new boolean[n + 1][m + 1];
        f[0][0] = true;
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(j >= nums[i - 1]) f[i][j] = f[i - 1][j - nums[i - 1]] || f[i - 1][j];
                else f[i][j] = f[i - 1][j];
            }
        }
        return f[n][m];
    }
}
复制代码

四、分析

时间复杂度分析: O(n∗m)nnums数组的大小,m是数组元素和的一半。

空间复杂度分析:O(n∗m)

posted @   ImreW  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示