ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

416. 分割等和子集 Partition Equal Subset Sum

2020-12-25 13:02:27  阅读:218  来源: 互联网

标签:Subset numsSize nums int Sum Partition mid sum left


题目 <https://leetcode-cn.com/problems/partition-equal-subset-sum/>

最初想法是两数之和,三数之和的思路

之后的想法是回溯法,直接超时。。。

void sort(int* nums, int numsSize)
{
	int left,right,mid,n;
    mid = 0;
    left = 1;
    right = numsSize -1;
	if(left>right)	return;
	while(left<=right)
	{
		while(left<=right&&nums[mid]<nums[right])	right--;
		if(left>right)	break;
		n = nums[right];
		nums[right] = nums[mid];
		nums[mid] = n;
		mid = right;
        right--;
		
		while(left<=right&&nums[mid]>nums[left])	left++;
		if(left>right)	break;
		n = nums[left];
		nums[left] = nums[mid];
		nums[mid] = n;
		mid = left;
        left++;
	}
	sort(nums,mid);
	sort(nums+mid+1,numsSize-mid-1);
}

bool canPack(int *nums,int numsSize,int sum,int sum_tmp,int i){
    //printf("%d %d\n",sum_tmp,sum);
    if(sum_tmp == sum){
        return true;
    }
    else if(sum_tmp > sum){
        return false;
    }

    int j;
    
    for(j=i;j<numsSize && sum_tmp+nums[j] <= sum;j++){
        if(canPack(nums,numsSize,sum,sum_tmp+nums[j],j+1) == true){
            return true;
        }
    }
    return false;
}

bool canPartition(int* nums, int numsSize){
    int i,j;
    int sum =0,sum1=0;
    for(i=0;i<numsSize;i++){
        sum += nums[i];
    }
    if(sum&1 == 1){
        return false;
    }
    sort(nums,numsSize);
    sum>>=1;

    return canPack(nums,numsSize,sum,0,0);
}

看了题解,怀疑人生。。。用动态规划解决N数和的另一种思路
 

bool canPartition(int* nums, int numsSize){
    int i,j;
    int sum =0;
    for(i=0;i<numsSize;i++){
        sum += nums[i];
    }
    if(sum&1 == 1){
        return false;
    }
    sum>>=1;
    bool **dp = malloc(sizeof(bool*) * numsSize);//dp[i][j]表示0~i的子集总和是否为j
    for(i=0;i<numsSize;i++){
        dp[i] = malloc(sizeof(bool) * (sum+1));
    }
    for(i=0;i<numsSize;i++){
        dp[i][0] = true;
    }

    for(i=0;i<1;i++){
        for(j=0;j<=sum;j++){
            dp[i][j] = (nums[i] == j);
        }
    }

    for(i=1;i<numsSize;i++){
        for(j=1;j<=sum;j++){
            if(j-nums[i]>=0){
                dp[i][j] = (dp[i-1][j] || dp[i-1][j-nums[i]]);
            }else{
                dp[i][j] = dp[i-1][j];
            }
        }
    }

    bool flag = dp[numsSize-1][sum];
    for(i=0;i<numsSize;i++){
        free(dp[i]);
    }
    free(dp);

    return flag;
}

 

标签:Subset,numsSize,nums,int,Sum,Partition,mid,sum,left
来源: https://blog.csdn.net/ZRXSLYG/article/details/111672479

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有