Day47:划分为两个不相交的子集

49 阅读1分钟

题目描述:

已知由n (M>2) 个正整数构成的集合A= {a<k<n) ,将其划分为两个不相交的子集A1和A2,元愫个数分别是n1和n2,A1和A2中的元素之和分别为S1和S2。设计一个尽可能高效的划分算法,满足|n1-n2|最小且|s1-s2|最大。要求:

题源:

[2016统考真题] image.png 1)给出算法的基本设计思想。

2)根据设计思想,采用C或C+ +语言描述算法,关键之处给出注释。

3)说明你所设计算法的平均时间复杂度和空间复杂度。

1、思路

根据快速排序,把数组分为上下两个部分,从中间分开就可以满足|n1-n2|最小且|s1-s2|最大

2、具体实现,根据设计思想,采用C或C+ +语言描述算法,关键之处给出注释。 /先利用partition函数把数组分为左右两个<pivot的部分 然后利用递归,分治;

//先利用partition函数把数组分为左右两个<pivot的部分
/** * 
分区过程 * a[] 待分区数组 * left 待分区数组最小下标 * right 待分区数组最大下标 
*/
int partition(int* arr , int low , int high) {
	int pivot = arr[low];
	while( low < high ) 
	{
		while( arr[high] >= pivot && high > low)
			high--;
		arr[low] = arr[high];
		while( arr[low] <= pivot && low < high )
			low++;
		arr[high] = arr[low];
	}
	arr[low] = pivot;
	return low;
}
利用递归,分治
/** * 
排序过程 * a 待排序数组 * left 待排序数组最小下标 * right 待排序数组最大下标 
* @return 排好序之后基准数的位置下标,方便下次的分区 
*/
void Quick_Sort(int arr[],int low,int high) 
{   
	if( low < high ) {
		int mid = partition(arr , low , high);
		Quick_Sort(arr , low , mid - 1);
		Quick_Sort(arr , mid + 1, high);
	}
}

1)给出算法的基本设计思想。

根据快速排序,把数组分为上下两个部分,从中间分开就可以满足|n1-n2|最小且|s1-s2|最大

3)说明你所设计算法的平均时间复杂度和空间复杂度。

时间复杂度:O(nlogn);

空间复杂度:O(n);