您的位置:首页 > 其它

GeeksForGeeks - Partition problem

2014-03-01 16:13 260 查看


Dynamic Programming | Set 18 (Partition problem)

Partition problem is to determine whether a given set can be partitioned into two subsets such that the sum of elements in both subsets is same.

Examples

arr[] = {1, 5, 11, 5}
Output: true 
The array can be partitioned as {1, 5, 5} and {11}

arr[] = {1, 5, 3}
Output: false 
The array cannot be partitioned into equal sum sets.

Following are the two main steps to solve this problem:

1) Calculate sum of the array. If sum is odd, there can not be two subsets with equal sum, so return false.

2) If sum of array elements is even, calculate sum/2 and find a subset of array with sum equal to sum/2.

The first step is simple. The second step is crucial, it can be solved either using recursion or Dynamic Programming.
http://www.geeksforgeeks.org/dynamic-programming-set-18-partition-problem/
Following are the two main steps to solve this problem:

解析为:

1 检查数组的总和是否是偶数,如果是基数就返回假

2 问题归结为在一个数组中寻找任意数组合的和等于一个数的问题(其中数组的数只能使用一次)。明白点说就是coin change问题(找零钱)

bool findPartiion (int arr[], int n)
{
	int sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += arr[i];
	}
	if (sum % 2) return false;
	sum /= 2;
	bool *A[2];
	A[0] = new bool[sum+1];
	A[1] = new bool[sum+1];
	
	A[0][0] = true;
	for (int i = 1; i <= sum; i++) A[0][i] = false;

	bool idx = true;
	A[1][0] = true;
	for (int i = 0; i < n; i++)
	{
		for (int j = 1; j <= sum; j++)
		{
			A[idx][j] = A[!idx][j];
			if (j >= arr[i] && !A[idx][j]) A[idx][j] = A[!idx][j-arr[i]];
		}
		if (A[idx][sum]) return true;
		idx = !idx;
	}
	return false;
}


原网站的解法效率:

Time Complexity: O(sum*n)

Auxiliary Space: O(sum*n)

Please note that this solution will not be feasible for arrays with big sum.

对比:

1 本博客程序时间效率基本上是一样的,不过实际运行应该快点,找到了找零方案就马上返回了,不用循环结束。

2 空间效率使用了O(sum),数组大的话,就节省了大量空间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: