交换两数组元素使两数组和差值最小

来源:互联网 发布:小宇热游淘宝 编辑:程序博客网 时间:2024/05/21 09:25
      题目:有两个数组a,b,大小都为n,数组元素的值任意,无序;

要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小

      很久之前就看到过这条题目,思路是有的,也没看网上其他人是怎么解的:

      1. A,B需要分别建最大堆(复杂度2N),维护各自的和值sumA,sumB,

      2. 如果堆A和堆B都非空;

      2. 如果sumA>=sumB,且{若max(A)>=max(B),交换A堆的根与B堆的根;若max(A)<max(B),不用交换},把堆B根加入到sumB中,去掉B堆的根,重新调整堆B;

      3. 如果sumA<sumB,且{若max(A)<=max(B),交换A堆的根与B堆的根;若max(A)>max(B),不用交换},把堆A根加入到sumA中,去掉A堆的根,重新调整堆A;

      4. 返回2

      最后得到交换后的数组与各自的和值sumA和sumB;

      复杂度计算:建堆复杂度为2N,每次循环要调整一次推,复杂度为lgN,有2N次循环,所以复杂度为NlgN。


      把代码写出来,练下手,先写直接点的数据版本:


void MaxHeapify(int * src, int pos,int count){int l = (pos<<1)+1;int r = l+1;int maxpos = pos;if (l<count && src[l]>src[pos]){maxpos = l;}if (r<count && src[r]>src[maxpos]){maxpos = r;}if (maxpos != pos){int temp = src[maxpos];src[maxpos] = src[pos];src[pos] = temp;MaxHeapify(src,maxpos,count);}}void CreateMaxHeap(int * src,int count){for (int t = count>>1;t>=0;--t){MaxHeapify(src,t,count);}return;}void swap(int &left,int &right){int temp = left;left = right;right= temp;}void SwapToGetMinDiff(int *A,int *B,int count){CreateMaxHeap(A,count);CreateMaxHeap(B,count);int *pA = &A[0];int *pB = &B[0];int sumA = 0;int sumB = 0;while (pA!=&A[count] && pB!=&A[count]){if ( sumA>=sumB ) {if (*pA >= *pB){swap(*pA,*pB);// 调整pA堆MaxHeapify(pA,0,&A[10]-pA+1);}sumB += *pB;pB++;//调整pB堆MaxHeapify(pB,0,&B[10]-pB+1);}else{if (*pA <= *pB){swap(*pA,*pB);//调整pB堆MaxHeapify(pB,0,&B[count-1]-pB+1);}sumA += *pA;pA++;//调整pA堆MaxHeapify(pA,0,&A[count-1]-pA+1);}}}int _tmain(int argc, _TCHAR* argv[]){int A[] = {0,1,2,3,4,5,6,7,8,9};int B[] = {10,11,12,13,14,15,16,17,18,19};SwapToGetMinDiff(A,B,10);int count = sizeof(A)/sizeof(A[0]);int sumA = 0;int sumB = 0;for (int i = 0; i<count;++i){printf("A[%d] = %d; \tB[%d] = %d;\n",i,A[i],i,B[i]);sumA+=A[i];sumB+=B[i];}printf("sum of A[] is %d\n",sumA);printf("sum of B[] is %d\n",sumB);return 0;}

上一张图

      上面的代码还有优化的空间,有时间的时候再整理一下。一直以A[0],B[0]为堆根,出堆的数据交换到尾段部分,初想有一点作用,但想了想,并没有降低复杂度。

      其实如果直接两个数组排序,复杂度为NlgN,再维护两个指针遍历两个数组,维护两个和值,最终的复杂度也是NlgN,而且觉得更好实现。

原创粉丝点击