二分数组差值最大
Posted zzbcoder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分数组差值最大相关的知识,希望对你有一定的参考价值。
假设n为偶数,现在要求将n个数分成两个等规模的集合s1,s2,并且使得s1中元素的和减去s2中元素之和的差是最大值。请写算法,并分析时间性能。
看到这个题目,直观理解,我想到了直接把这个数组中的数字进行排序,元素之和的差最大,也当然就是排序过后的前一半和后一半元素差值最大,显然,一个快速排序可以满足这个要求。快排的时间复杂度为O(nlgn)
考虑到分治思想,该如何进行优化。例如二分搜索的基本思想是,将n个元素分成两个等规模的集合s1,s2,取a[n/2]与x相比较。如果x=a[n/2],则找到x,终止算法;如果x=a[n/2],则在数组a的左半部分继续搜索x;如果x=a[n/2],则在右边寻找。在最坏情况下,while循环被执行了O(logn)次。循环体内运算需要O(1)时间,因此整个算法在最坏情况下的时间复杂性为O(logn)。
利用快速排序的划分思想,设正整数集合为数组S,划分为前半个数组S1,后半个数组为S2,若第一次划分的轴值是中位数,则返回;若不是继续划分中位数所在的部分。
考虑快排中的分治思想
如果s1 (大的数集)的的个数大于n/2
将(i<=n/2-loW-1)个最小的数排到后面
如果s1 (大的数集)的的个数小于n/2
将s2 (小的数集) n/2-low-1排到前面
将排好的数组的前n/2个数赋值给s1
将排好的数组的后n/2个数赋值给s2
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
const int n = 8;
void partions(int a[], int low, int high)
//进行一趟快排
int key = a[low];
a[0] = a[low];
while (low < high)
while (low < high && a[high] <= key)
--low;
a[low] = a[high];
while (low < high && a[low] >= key)
++low;
a[high] = a[low];
a[low] = key;
//如果s1(大的数集)的的个数大于n/2
if (low >= n / 2)
for (int i = 0; i <= n / 2 - low - 1; ++i)
for (int j = 0; j < n - 1; ++j)
if (a[j] < a[j + 1])
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
//如果s1(大的数集)的的个数小于n/2 else
else
for (int i = 0; i <= n / 2 - low - 1; ++i)
for (int k = n - 1; k < n - i; ++k)
if (a[k] > a[k - 1])
int temp1 = a[k];
a[k] = a[k - 1];
a[k - 1] = temp1;
int main()
int a[n] = 1, 3, 5, 9, 6, 0, -11, -8;
partions(a, 0, n - 1);
for (int i = 0; i < n; ++i)
if (i < 4)
cout << "属于子集s1的" << endl;
cout << "属于子集s2的" << endl;
cout << a[i] << endl;
return 0;
时间复杂度O(n),空间复杂度O(1)。
以上是关于二分数组差值最大的主要内容,如果未能解决你的问题,请参考以下文章