求Maximim Gap 排序后的两个相邻元素之间的最大差值

方法、桶排序

为了满足O(n)复杂度,尝试计数排序,但是会TLE。因此使用桶排序来做

计数排序可以看做是桶大小为1的桶排序,但由于桶数目太多导致遍历时间过长

最大gap肯定是出现在后一个有效桶的min与前一个有效桶的max之间

(“有效”指的是忽略空桶)

步骤思路:

1、数组中有N个元素,最小元素为min、最大元素为max

2、平均间隔为gap = ceil( (max - min) / (N - 1))  ceil指结果向上取整

3、总共分成 bucketCount =ceil((max - min)/ gap ) 个区间(一个区间也就是一个桶),每个区间元素范围是 [ min + k * gap , min + (k + 1) * gap )

4、每个元素对应的桶号(区间)为  bucketNum = (kVal - min)/ gap

桶排序,由于num中的数字肯定在[min,max]区间内

所以根据抽屉原理,假设num中有n个数字,则最大的gap必然要大于dis=(max-min)/(n-1)

所以我们可以把num所在的范围分成等间隔的区间,相邻区间内的元素之间的最大差值,即为要寻找的gap

class MaxDivision {
public:
	int findMaxDivision(vector<int> A, int n) {
		if (n < 2)
			return 0;
		// write code here
		int max_val = *max_element(A.begin(), A.end());
		int min_val = *min_element(A.begin(), A.end());

		//平均间距一定要向上取整,只能多不能少,因为少了会导致计算桶号时比实际的偏大以至于超过桶数
		int avg_gap = ceil((double)(max_val - min_val) / (n - 1));

		//first is the min value of this bunket,second is the max value of this bunket
		//桶的数量直接 n - 1 就行了
		vector<std::pair<int, int>> bunket(n - 1, make_pair(INT_MAX, INT_MIN));

		for (auto num : A) {
			if (num == max_val || num == min_val)
				continue;
			int bunket_num = (num - min_val) / avg_gap;
			if (num < bunket[bunket_num].first)
				bunket[bunket_num].first = num;
			if (num > bunket[bunket_num].second)
				bunket[bunket_num].second = num;
		}

		int maxGap = 0; //return value
		int lastMax = min_val;
		for (auto val : bunket) {
			if (val.first == INT_MAX)
				continue;
			int tmp = val.first - lastMax;
			maxGap = tmp > maxGap ? tmp : maxGap;
			lastMax = val.second;
		}
		int tmp = max_val - lastMax;
		maxGap = tmp > maxGap ? tmp : maxGap;
		return maxGap;
	}
};


你可能感兴趣的:(算法)