1、有一个整数数组,求出两两只差绝对值最小

/************************************************************************/
/* 1、有一个整数数组,求出两两只差绝对值最小                        */
/************************************************************************/
int iCompare(const void* lhs, const void* rhs)
{
	return *(const int *)lhs - *(const int *)rhs;
}

//使用快速排序的方法,时间复杂度O(nlogn), 空间O(1)
int minSubBySort(int *iArr, int length)
{
	if(!iArr || length < 2)
		throw new exception("error");
	
	//从小到大排序
	qsort(iArr, length, sizeof(int), iCompare);
	
	//遍历求解最小差值
	int minSub = numeric_limits<int>::max();
	for(int i = 0; i < length - 1; ++i)
	{
		int curSub = iArr[i + 1] - iArr[i];
		if(minSub > curSub)
			minSub = curSub;
	}
	return minSub;
}


void insertSort(vector<int>& ivect)
{
	for(unsigned i = 1; i < ivect.size() ; ++i)
	{
		for(int j = i - 1; j >= 0; --j)
		{
			if(ivect[j + 1] < ivect[j])
			{
				int temp = ivect[j + 1];
				ivect[j + 1] = ivect[j];
				ivect[j] = ivect[j + 1];
			}
			else
				break;
		}
	}
}
//快速排序换成桶排序时间O(n), 空间O(n)
int minSubByBucketSort1(int * arr, int length)
{
	//一共length个桶, 每个桶步长为h = maxSub / (length - 1), [min, min + h), [min + h, m + 2h)...
	// 找打最大最小元素
	int minVal = arr[0];
	int maxVal = arr[0];
	for(int i = 1; i < length; ++i)
	{
		if(arr[i] > maxVal)
			maxVal = arr[i];
		if(arr[i] < minVal)
			minVal = arr[i];
	}
	
	//计算h
	int h = (int)ceil((maxVal - minVal)/double(length -1));
	//length个桶,数组中元素放入桶中
	vector<int>* vectArr = new vector<int>[length];
	for(int j = 0; j < length; ++j)
	{
		int pos = (arr[j] - minVal) / h;
		vectArr[pos].push_back(arr[j]);
	}
	//对桶中元素排序
	for(int k = 0; k < length; ++k)
	{
		insertSort(vectArr[k]);
	}
	int curMin = numeric_limits<int>::max();
	int preMax = numeric_limits<int>::min();
	int curMax = numeric_limits<int>::min();
	int minSub = numeric_limits<int>::max();
	for(int l = 0; l < length; ++l)
	{
		//桶间比较
		if(vectArr[l].size() == 0)
			break;
		else
		{
			curMin = vectArr[l][0];
			curMax = vectArr[l][vectArr[l].size() - 1];
			if(preMax != numeric_limits<int>::min())
				minSub = minSub < abs(curMin - preMax) ? minSub : abs(curMin - preMax);

		}
		//桶内比较
		for(unsigned m = 0; m < vectArr[l].size() - 1; ++m)
		{
			int absSub = vectArr[l][m+1]- vectArr[l][m];
			if( absSub < minSub)
				minSub = absSub;
		}
		preMax = curMax;

	}
	//
	return minSub;
}

//桶排序方法时间O(n), 空间O(2n),桶内元素不排序
//桶范围h:maxSub = max - min, h = maxSub / (n - 1), [min, min + h), [min + h, m + 2h)...
//至少有一个桶中元素数量大于2,计算每个桶中的最小差值,与相邻桶最小差值(此桶最小值 - 上桶最大值)
//比较求得minSub
bool findMinSubOfVector(const vector<int>& iVect, int& result)
{
	vector<int>::const_iterator beg = iVect.begin();
	if(iVect.size() < 2)
		return false;
	result = numeric_limits<int>::max();
	while(beg != iVect.end())
	{
		vector<int>::const_iterator pIter = beg + 1;
		while(pIter != iVect.end())
		{
			if(abs(*beg - * pIter) < result)
				result = abs(*beg - *pIter);
			++pIter;
		}
		++beg;
	}
	return true;
}
int minSubByBucketSort(int * arr, int length)
{
	if(!arr || length < 2)
		throw new exception("error!");

	// 找打最大最小元素
	int minVal = arr[0];
	int maxVal = arr[0];
	for(int i = 1; i < length; ++i)
	{
		if(arr[i] > maxVal)
			maxVal = arr[i];
		if(arr[i] < minVal)
			minVal = arr[i];
	}

	//计算h
	int h = (int)ceil((maxVal - minVal)/double(length -1));
	//length个桶,数组中元素放入桶中
	vector<int>* vectArr = new vector<int>[length];
	for(int j = 0; j < length; ++j)
	{
		int pos = (arr[j] - minVal) / h;
		vectArr[pos].push_back(arr[j]);
	}
	//计算每个桶的minSub,并找到最大最小值 
	int preMax = numeric_limits<int>::min(), curMin = numeric_limits<int>::max();
	int curMax = preMax;
	int minSub = numeric_limits<int>::max();
	for(int k = 0; k < length; ++k)
	{
		if(vectArr[k].size() == 0)
			continue;
		//计算桶内的minSub
		int tempMinSub = numeric_limits<int>::max();
		if(findMinSubOfVector(vectArr[k], tempMinSub) && minSub > tempMinSub)
			minSub = tempMinSub;

		//当前桶最小值和最大值
		vector<int>::iterator beg = vectArr[k].begin();
		curMax = *beg;
		curMin =  *beg;
		while(beg != vectArr[k].end())
		{
			if(curMax < *beg)
				curMax = *beg;
			if(curMin > *beg)
				curMin = *beg;
			++beg;
		}
		
		//桶间最大最小值
		if(k > 0)
		{
			tempMinSub = curMin - preMax;
			if(minSub > tempMinSub)
			minSub = tempMinSub;
		}
		preMax = curMax;

	}

	delete[] vectArr;
	return minSub;
	
}


void testofGetMinSub()
{
	const int size = 100000;
	int arr[size];
	//随机生成size不同的数
	int rangle = size * 10;
	int selected = 0;
	for(int i = 0; i < rangle && selected < size; ++i)
	{
		if(rand() % (rangle - i) < size - selected)
			arr[selected++] = i; 
	}
	
	//showArr(arr, size);

	DWORD start = GetTickCount();

		cout << "minsub = " << minSubBySort(arr, size) << endl;

	DWORD end = GetTickCount();
	cout << end - start << endl;

	start = GetTickCount();
	cout << "minsub = " << minSubByBucketSort(arr, size) << endl;
	end = GetTickCount();
	cout << end - start << endl;

	start = GetTickCount();
	cout << "minsub = " << minSubByBucketSort1(arr, size) << endl;
	end = GetTickCount();
	cout << end - start << endl;
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值