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

来源:互联网 发布:薪酬数据分析 模板 编辑:程序博客网 时间:2024/06/05 07:23
/************************************************************************//* 1、有一个整数数组,求出两两只差绝对值最小                        *//************************************************************************/
//先排序后求值,快速排序O(nlogn),桶排序O(n),但空间也是O(n)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];}elsebreak;}}}//快速排序换成桶排序时间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];}//计算hint 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,计算每个桶中的最小差值,与相邻桶最小差值(此桶最小值 - 上桶最大值)//比较求得minSubbool 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];}//计算hint 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;//计算桶内的minSubint 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;}

原创粉丝点击