1、有一个整数数组,求出两两只差绝对值最小
2012-09-05 10:12
211 查看
/************************************************************************/ /* 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; }
相关文章推荐
- 1、有一个整数数组,求出两两只差绝对值最小
- 输入一个整数数组,返回所有元素两两之差绝对值最小的值,O(n)算法
- 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。 (微软面试题)
- 微软1 有一个整数数组,请求出两两之差绝对值最小的值
- 有一个整数数组,请求出两两之差绝对值最小的值
- 求最小绝对值子串、一个整数数组求两两之差绝对值最小值
- 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
- 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
- 有一个整数数组,请求出两两之差绝对值最小的值
- 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数
- 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
- 有一个整数数组,请求出两两之差绝对值最小的值
- 有一个整数数组,请求出两两之差绝对值的最小值
- 有一个整数数组,请求出两两之差绝对值最小的值
- 一道面试题:有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
- 有一个整数数组,请求出两两之差绝对值最小的值
- 微软面试-101-有一个整数数组,请求出两两之差绝对值最小的值,
- 有一个整数数组,请求出两两之差绝对值最小的值, 记住,只要得出最小值即可,不需要求出是哪两个数。
- 给定一个无序整型数组,找出数组中未出现的最小整数
- 求一个已排序的数组中绝对值最小的元素