### 416. Partition Equal Subset Sum 题目: 难度: Medium 记得算法考试考过证明这个问题是NP的,当时用的是subset sum是NP,然后来证明这个?如果我们能找到一个subset的sum是整个array sum的一半,那么问题解决。subset sum我们又可以继续转化,转成背包问题。 值得注意的是,这是subset sum,并不是subarray sum(这个明显要简单一些,因为subarray是连着的). subset sum也是有自己的[wikipedia page](https://en.wikipedia.org/wiki/Subset_sum_problem). 当然,这也是一个subset problem,我们当然也可以用subset,加入和不加入,但是worst case O(2^n). 对于subset sum的递推方程式: subset(arr,n,s) = subset(arr,n-1,s) or subset(arr, n-1, s- arrp[n-1]) 画表可以开始,第一列全为1,是因为不选全部可以为0 ``` 0 1 2 3 4 5 6 8 9 10 11 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 5 1 1 0 0 0 1 1 0 0 0 0 5 1 1 0 0 0 1 1 0 0 0 1 ``` 所以伪多项式算法写出来 AC代码 ``` class Solution(object): def canPartition(self, nums): """ :type nums: List[int] :rtype: bool """ def subset(nums, s): dp = [[0 for i in range(s+1) ] for j in range(len(nums)+1)] dp[0][0] = 1 # init the first col for i in range(len(nums)+1 dp[i][0] = 1 for i in range(1,len(nums)+1): for j in range(1,s+1): if dp[i-1][j] == 1: dp[i][j] = 1 elif j >= nums[i-1] and dp[i-1][j-nums[i-1]] ==1: dp[i][j] = 1 return dp[-1][-1] == 1 total = sum(nums) if total % 2 == 1: return False else: half = total / 2 return subset(nums,half) == 1 ``` 当然可以小调整,比如一旦发现,提前return等等,但是时间上依旧是后20%,不知道时间上快很多的人是如何做到的|||