LeetCode 最大间距

给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。

示例 1:

输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。

示例 2:

输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。

说明:

你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。

思路分析:需要知道最大间距,那么一般来说是要先进行排序的,时间复杂度为O(n)的排序方法中,好像我就知道计数排序、桶排序。
方法一:使用map容器辅助,进行计数排序。(但是map自动排序的复杂度貌似是O(nlogn))

class Solution {
public:
	int maximumGap(vector<int>& nums) {
		int numsSize = nums.size();
		if (numsSize < 2) {
			return 0;
		}
		map<int, int> myMap;//辅助容器,用于标记各个元素的出现的次数
        //扫描nums
		for (int index = 0; index < numsSize; ++index) {
			++myMap[nums[index]];
		}
		int maxGap = 0;//存放结果
		map<int, int>::iterator before = myMap.begin();
        //再次扫描容器,判断排序好的左右两端的间距差
		for (map<int, int>::iterator it = ++myMap.begin(); it != myMap.end(); ++it) {
			int tempValue = it->first - before->first;
			maxGap = max(maxGap, tempValue);//更新结果
			++before;
		}
		return maxGap;
	}
};

在这里插入图片描述
方法二:使用桶排序,但不建立正真的桶,而是虚设的桶,只保留桶中的最大值、最小值。桶的数量为nums.size() + 1,所以每个桶至多只有一个元素,(且最小值放在第一个桶,最大值放在最后一个桶),只设立每个桶的最大值、最小值变量。再将所有元素都放入它应该在的桶序号,最后扫描所有的桶,求出间距。

class Solution {
public:
    //将 num 映射到对应的桶子
    int mapToBucket(long num, long len, long min, long max) {
        return (int) ((num - min) * len / (max - min));
    }
	int maximumGap(vector<int>& nums) {
		int numsSize = nums.size();
		if (numsSize < 2) {
			return 0;
		}
		int maxValue = *max_element(nums.begin(), nums.end());//获取桶中的最大值
		int minValue = *min_element(nums.begin(), nums.end());//获取桶中的最小值
		if (maxValue == minValue) {
			return 0;
		}
		int bucketCnt = numsSize + 1;//桶的个数
		vector<int> maxBucket(bucketCnt, INT_MIN);//新建长度bucketSize的vector容器,maxBucket[i]用于保存第i个桶的最大值
		vector<int> minBucket(bucketCnt, INT_MAX);//新建长度bucketSize的vector容器,minBucket[i]用于保存第i个桶的最小值
		maxBucket[0] = minBucket[0] = minValue;//第一个桶只保存最小值
		maxBucket[bucketCnt - 1] = minBucket[bucketCnt - 1] = maxValue;//最后一个桶只保存最大值
		for (auto num : nums) {
			int bucketIndex = mapToBucket(num, numsSize, minValue, maxValue);//这个元素应该放的桶的序号
			maxBucket[bucketIndex] = max(maxBucket[bucketIndex], num);//更新这个桶中的最大值
			minBucket[bucketIndex] = min(minBucket[bucketIndex], num);//更新这个桶中的最小值
		}
		int maxGap = INT_MIN, preIndex = 0;
        //扫描所有的桶,计算桶之间的间距
		for (int index = 1; index < bucketCnt; ++index) {
            //跳过空桶
			while (preIndex < bucketCnt && maxBucket[preIndex] == INT_MIN) {
				++preIndex;
			}
			if (preIndex == bucketCnt) {
				break;
			}
			index = preIndex + 1;
            //跳过空桶
			while (index < bucketCnt && maxBucket[index] == INT_MIN) {
				++index;
			}
			if (index == bucketCnt) {
				break;
			}
            //更新间距
			maxGap = max(maxGap, minBucket[index] - maxBucket[preIndex]);
			preIndex = index;
		}
		return maxGap;
	}
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/87917978