算法学习7-桶排序的例题=> 相邻两数最大

算法学习-桶排序的具体例题<高频题目>相邻两数最大插值

问题描述:
给定一个数组,求排序之后的最大差值,且时间复杂度为O(N),额外空间复杂度为O(1)的算法,且要求不能用非比较的排序算法。

问题分析 && 算法实现

  1. 将待排序元素划分到不同的桶。先扫描一遍序列求出最大值 maxV 和最小值 minV ,设桶的个数为 k ,则把区间 [minV, maxV] 均匀划分成 k +1个区间,每个区间就是一个桶。将序列中的元素分配到各自的桶。
    2.根据鸽笼原理(鸽笼原理简单表述:若有n个笼子和n+1只鸽子,所有的鸽子都被关在鸽笼里,那么至少有一个笼子有至少2只鸽子。推广:如果要把n个物件分配到m个容器中,必有至少一个容器容纳至少⌈n / m⌉个物件。(⌈x⌉大于等于x的最小的整数))可以得知至少有一个空桶(空桶的意义在于否定最大插值在同一个桶中出现),
    3.去遍历一遍数组,去记录每个桶中的最大值和最小值及每个桶是否是空桶.
    4.去找相邻两个桶的最大差值(及后一个桶的最小值和相邻的前一个非空桶的最大值)
    5.最后结果即在这些记录的最大值中.即找出这些跨桶最大值中的最大值.

代码实现:

#include<iostream>
#include<cstdlib>
using namespace std; 

//求出每一个数所在的桶的编号
int bocketNum(int a[], int i, int min, int max, int len){
	return (a[i]-min) * len / (max-min);
}
int Min(int a, int b){
	return a <= b ? a : b;
}
int Max(int a, int b){
	return a >= b ? a : b;
}

int maxGap(int A[], int n)
{
	int min = A[0];
	int max = A[0];
	
	//找出最大值和最小值
	for(int i = 1; i < n; ++i){
		min = (min <= A[i] ? min : A[i]);
		max = (max >= A[i] ? max : A[i]);
	}
	
	int* minArr = new int[n+1]();//记录每个桶中的最小数
	int* maxArr = new int[n+1]();//记录每个桶中的最大数
	bool hasNum[n+1] = {0};//记录桶中是否有数
	
	for(int i = 0; i < n; ++i){
		//求出每一个数所在的桶的编号
		int bocketID = bocketNum(A, i, min, max, n);
		minArr[bocketID] = hasNum[bocketID] ? Min(minArr[bocketID], A[i]) : A[i];
		maxArr[bocketID] = hasNum[bocketID] ? Max(maxArr[bocketID], A[i]) : A[i];
		hasNum[bocketID] = true;
	}
	
	int MaxGap = 0;//记录最大差值
	int LastMax = 0;//记录当前空桶的上一个桶的最大值
	
	int i = 0;
	while(i < n + 1){	//可能会有多个空桶
		//遍历桶,找到一个空桶
		while(i < n + 1 && hasNum[i])
			i++;
		if(i == n + 1)
			break;
		LastMax = maxArr[i-1];
		//继续遍历桶,找到下一个非空桶
		while(i < n + 1 && !hasNum[i])
			i++;
		if(i == n + 1)
			break;
		MaxGap = Max(MaxGap, minArr[i]-LastMax);
	}
	delete []minArr;
	delete []maxArr;
	
	return MaxGap;
}
 
int main(void)
{
	int NUMBER; 
	cin>>NUMBER;
    int *p;
    p=new int[NUMBER];
    
	for(int k=0;k<NUMBER;k++)
    {
        p[k]=rand()%NUMBER;
    }
    
    for(int i=0;i<NUMBER;i++)
    {
      cout<<p[i]<<" ";
    }
    cout<<endl;
    
	cout<<maxGap(p,NUMBER)<<endl<<endl;
	
	return 0;
}

发布了27 篇原创文章 · 获赞 1 · 访问量 1046

猜你喜欢

转载自blog.csdn.net/qq_45205390/article/details/103555315