我正在解决Partition Equal Subset Sum的leetcode。
问题状态:
Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Note:
Each of the array element will not exceed 100.
The array size will not exceed 200.
我将以下代码写为
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
}
if(sum%2!=0)
{
return false;
}
int target=sum/2;
return helper(nums,target,nums.length);
}
boolean helper(int nums[],int sum,int n)
{
if(sum==0)
{
return true;
}
if(sum<0)
{
return false;
}
if(n==0)
{
return false;
}
return helper(nums,sum-nums[n-1],n-1)||helper(nums,sum,n-1);
}
}
请注意,我没有包含该条件
if(sum<nums[n-1])
{
return false;
}
在我包括的基本情况下
if(sum<0)
{
return false;
}
这与将只添加1个递归调用然后返回false相同。
此代码适用于89个测试用例,但给出
的TLE错误[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,100]
现在,如果修改相同的代码并包含
if(sum<nums[n-1])
{
return false;
}
并删除
if(sum<0)
{
return false;
}
即
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
}
if(sum%2!=0)
{
return false;
}
int target=sum/2;
return helper(nums,target,nums.length);
}
boolean helper(int nums[],int sum,int n)
{
if(sum==0)
{
return true;
}
if(n==0)
{
return false;
}
if(nums[n-1]>sum)
{
return false;
}
return helper(nums,sum-nums[n-1],n-1)||helper(nums,sum,n-1);
}
}
该代码可以正常工作并通过所有测试用例。
由于两个代码都相同,那么一个额外的递归调用如何给我TLE? 还有别的吗?
答案 0 :(得分:0)
测试用例确实很弱。第一个应该获得TLE,因为您没有使用动态编程,但是执行了简单的回溯。第二个应该得到WA。如果使用记忆,则复杂度为O( totalSum * arraySize)
,但代码的复杂度为O(2 ^ arraySize)。
现在观察您在每种状态下都有两个选择。您是否选择元素。即使此条件为if(nums[n-1]>sum)
,第二个选项仍然有效-继续不选择项目。但是您的第二个代码会忽略这种情况的两种情况,从而将调用减少到解决方案所需的时间少于1毫秒,这比大多数正确的解决方案要快。由于第二个解决方案没有反测试用例,因此它通过了。