求无序数组排序后相邻两个数的最大差值

方法一(位图法):

  • 遍历原数组,求出最大值Max和最小值Min;
  • 创建一个长度为k(k=Max-Min+1)的新数组Array;
  • 遍历原数组,把原数组每一个元素插入到新数组Array对应的位置,比如元素的值为n,则插入到Array[n-min]当中。此时Array的部分位置为空,部分位置填充了数值。
  • 遍历新数组Array,统计出Array中最大连续出现空值的次数+1,即为相邻元素最大差值。

** 缺点:当数组中元素悬殊很大时,如1、2、100000000,则需要构造一个长度是100000000的新数组Array,则该方法不可取。**

方法二(桶排序):

假设原数组长度为N

  • 遍历原数组,求出最大值Max和最小值Min;
  • 将最小值Min与最大值Max所界定的区间划分成N+1个桶,每个桶的区间长度为d=(Max-Min)/N;
  • 创建一个长度是N+1的数组Array,数组中的个元素是List,代表一个桶;

    这样每个桶的区间范围:[Min, Min+d)、[Min+d, Min+2d)、[Min+2d, Min+3d)、…、[Min+(N-1)d, Min+Nd=Max)、[Min+Nd=Max, Min+Nd=Max]

  • 遍历原数组,把原数组中的每一个元素插入到新数组Array对应的桶当中,进入各个桶的条件是根据不同的数值区间;

    由于桶的总数量是N+1,故至少有一个桶是空的,且空桶肯定不是第一个(至少有Min)和最后一个桶(有Max)。

最大差值肯定出现在空桶附近。(非空桶内部最大差值<d,空桶左边第一个非空桶的最大值 与 空桶右边第一个非空桶的最小值 > d)

  • 遍历新数组Array,计算每一个空桶右端非空桶中的最小值,与空桶左端非空桶的最大值的差。数值最大的差即为原数组排序后的相邻最大差值。

空间复杂度:O(N),时间复杂度:O(N)(总共扫描3次)。

实现

int maxGap(std::vector<int> &vecNum)
{
	// 获取最大值与最小值
	int nMax = vecNum[0], nMin = vecNum[0];
	for (int nIndex = 1; nIndex < vecNum.size(); nIndex++)
	{
		if (nMax < vecNum[nIndex])
		{
			nMax = vecNum[nIndex];
		}
		else if (nMin > vecNum[nIndex])
		{
			nMin = vecNum[nIndex];
		}
	}

	// 桶的个数
	int nBucketNum = vecNum.size() + 1;
	// 每个桶的区间长度
	int nBucketLength = (nMax - nMin) / vecNum.size();

	// 记录桶的最小值
	std::vector<int> vecBucketMin(nBucketNum, INT_MAX);
	// 记录桶的最大值
	std::vector<int> vecBucketMax(nBucketNum, INT_MIN);

	// 获取每个桶内的最小和最大值
	for (int nIndex = 0; nIndex < vecNum.size(); nIndex++)
	{
		// 映射到某一个桶
		int nBucketIndex = (vecNum[nIndex] - nMin) / nBucketLength;

		// 记录桶的最大和最小值
		if (vecBucketMax[nBucketIndex] < vecNum[nIndex])
		{
			vecBucketMax[nBucketIndex] = vecNum[nIndex];
		}
		
		if (vecBucketMin[nBucketIndex] > vecNum[nIndex])
		{
			vecBucketMin[nBucketIndex] = vecNum[nIndex];
		}
	}

	// 计算每一个空桶右端非空桶中的最小值,与空桶左端非空桶的最大值的差
	int nMaxGap = 0;
	int nPreMax = vecBucketMax[0];
	bool nEmptyBucket = false;
	for (int nBucketIndex = 1; nBucketIndex < nBucketNum; nBucketIndex++)
	{
		if (vecBucketMin[nBucketIndex] != INT_MAX)
		{
			// 非空桶
			if (nEmptyBucket)
			{
				// 前一个是空桶
				nMaxGap = vecBucketMin[nBucketIndex] - nPreMax;
			}
			
			nPreMax = vecBucketMax[nBucketIndex];
			nEmptyBucket = false;
		}
		else
		{
			// 空桶
			nEmptyBucket = true;
		}
	}

	return nMaxGap;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值