1 | 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 |
Leetcode官方就解题思路
前言
作者在这里希望读者认真阅读前言部分。
本题是经典的NP 完全问题,也就是说,如果你发现了该问题的一个多项式算法,那么恭喜你证明出了 P=NP,可以期待一下图灵奖了。
正因如此,我们不应期望该问题有多项式时间复杂度的解法。我们能想到,例如基于贪心算法的「将数组降序排序后,依次将每个元素添加至当前元素和较小的子集中」之类的方法都是错误的,可以轻松地举出反例。因此,我们必须尝试非多项式时间复杂度的算法,例如时间复杂度与元素大小相关的动态规划。
方法一:动态规划
思路与算法
这道题可以换一种表述:给定一个只包含正整数的非空数组 nums[0],判断是否可以从数组中选出一些数字,使得这些数字的和等于整个数组的元素和的一半。因此这个问题可以转换成「0-1 背包问题」。这道题与传统的「0-1 背包问题」的区别在于,传统的「0-1 背包问题」要求选取的物品的重量之和不能超过背包的总容量,这道题则要求选取的数字的和恰好等于整个数组的元素和的一半。类似于传统的「0-1 背包问题」,可以使用动态规划求解。
在使用动态规划求解之前,首先需要进行以下判断。
1 | class Solution { |
Liture解题思路
1 | /** |
1 | 刚开始动态规划不太理解,后来发现: |
1 | /*而第0行非常容易求。dp[0][s] = true当且仅当nums[0]==s*/ |
1 |
|
1 | 优化版本: |
1 | //图解: |
1 | // d(i, s) : 是否存在:nums区间[0, i] 中取一些元素,使其和为s |
1 | 优化版本: |
1 | class Solution { |
1 | /*最后,这里给出最简的一维数组动态规划代码*/ |
1 | class Solution { |
参考文献
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/partition-equal-subset-sum/solution/fen-ge-deng-he-zi-ji-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。