相邻两数最大差值

相邻两数最大差值 文章目录一、问题二、解题思路。三、代码实现(Java) 一、问题 给定一个数组,求如果排序之后,相邻两数最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。 二、解题思路。 已知数组长度为 n。 遍历数组,找到整个数组中元素最大值 max 和最小值 min 。 根据找到的 max 和 min,将数组均匀划分为 n + 1 个范围。 遍历数组,根据每个数组元素的值,判断进入对应的范... 阅读详情


有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。

给定一个int数组AA的大小n,请返回最大的差值。保证数组元素多于1个。

测试样例:
[1,2,5,4,6],5
返回:2


解析:使用bucket排序思想,把大小为n的数组分成(max-min)/n个区间,显然这个区间是1 ~ n。

映射函数如下:

((num - min) * n / (max - min));

这样写是因为(num-min) / ((max-min) / n) =  ((num - min) * n / (max - min));

比如num=6,min=1,max=6,(6-1) * 5 / (6-1) = 5,所以6在5号桶。这个映射函数决定了桶序号不可能为0,所以编程时要先剔除为0的空桶。

由于在任何一个桶中任何两个数的差值都不可能大于区间差值,而在空桶左右两边不空的桶里,相邻数的差值肯定大于区间值。所以产生最大差值的两个相邻数肯定来自不同的桶。所以只要计算桶之间数的间距就可以,也就是只用记录每个桶的最大值和最小值,最大差值可能来自某个非空桶的最小值减去前一个非空桶的最大值。


代码如下:

class Gap {
public:
    int maxGap(vector<int> A, int n) {
       	if(n < 0 || ((A.size()==0) ^ (n==0)))
            return -1;
               
        int res = 0;
       	if(n < 2)
        	return res;
               
        int max = A[0], min = A[0];
        for(int i=1; i<n; ++i){
            if(A[i] > max)
                max = A[i];
           	if(A[i] < min)
                min = A[i];
        }
        if(max == min)
        	return res;
        
        vector<bool> has_num(n+1, false);   //用来标记是否是非空桶
        vector<int> maxs(n+1, 0);
        vector<int> mins(n+1, 0);
        for(int i=0; i<n; ++i){
            int bucket_id = get_bucket_id(A[i], n, min, max);
            maxs[bucket_id] = has_num[bucket_id] ? std::max(maxs[bucket_id], A[i]) : A[i];
            mins[bucket_id] = has_num[bucket_id] ? std::min(mins[bucket_id], A[i]) : A[i];
            has_num[bucket_id] = true;
        }
        
        int k = 0;
        int last_max = 0;
        while(k <= n){
            if(has_num[k]){
               last_max = maxs[k];   //排除序号为0的空桶,因为前面都是空桶,不是数据,相邻最大差是数据与数据之间的最大差,所以第一个last_max=maxs[k],
               break;                //从下一个mins减去这个last_max开始找出最大的差
            }
           	++k;
        }
        
       	while(++k <= n){
            if(has_num[k]){       //只有非空桶才可以进入,所以res一直为两个非空桶的差
                res = std::max(mins[k]-last_max, res);
                last_max = maxs[k];   //注意更新last_max
            }
        }
        
        return res;
    }
private:
    int get_bucket_id(long long num, long long n, long long min, long long max){   //使用long long类型防止溢出
        return (int)((num - min) * n / (max - min));
    }
};

整段程序的核心就是:

     
       	while(++k <= n){
            if(has_num[k]){       //只有非空桶才可以进入,所以res一直为两个非空桶的差
                res = std::max(mins[k]-last_max, res);
                last_max = maxs[k];   //注意更新last_max
            }
        }

这一段程序通过++k保证了在之前k的基础上加1,has_num[k]保证只有非空桶进入该条件,所以相邻两个非空桶就会进入,并计算res。我们要注意更新last_max。


相邻两数最大差值 -- 算法小结 有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数最大差值。给定一个int数组A和A的大小n,请返回最大差值。保证数组元素多于1个。测试样例: [1,2,5,4,6],5 返回:2编程思路:本题明显就是先排序,后比较相邻数的差值,因此有很多的实现方法,首先就是排序,我们可以选择复杂度较低的算法,这里使用类似桶排序的思想,我们不是以元素的值来计算桶的数目,而是元素个数来划分 阅读详情

相关推荐

相邻最大差值

题目:    请设计一个复杂度为O(n)的算法,计算一个未排序数组中排序后相邻元素最大差值。    给定一个整数数组A和数组的大小n,请返回最大差值。 代码:    /* *分析: * 这是一个典型的利用桶排序求解问题,因为桶排序不少基于比较的排序可以打破nlogn的下限, * 可以达到题目要求的复杂度n * 相邻两个差值最大 肯定大于平均值 平

吴蕴强的博客 1143

相邻两数最大差值 c++

题目:给定一个数组,求如果排序之后,相邻两数最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。 思路:因为不能使用非基于比较的排序,所以不能应用桶排序后遍历找最大差值。但可以应用桶排序的思想:创建一个比原数组个数加一的桶,数组的最小值放在第0号桶里,数组的最大值放在最后一个桶里,然后遍历数组,桶内只放该区域的最大值和最小值。遍历之后中间一定会有一个空桶,要注意的是空桶的左边的最小值...

weixin_44177074的博客 1844

C++相邻最大差值

1. 题目描述 相邻最大差值 请设计一个复杂度为O(n)的算法,计算一个未排序数组中排序后相邻元素最大差值。 给定一个整数数组A和数组的大小n,请返回最大差值。保证数组元素个数大于等于2小于等于500。 测试样例: 输入: [9,3,1,10],4 输出:返回:6 2. 思路 首先求出数组的最大值max和最小值min; 然后将该区间均等的划分为n+1份,即n+1个桶,那么由于只有...

暮日落流年的博客 1659

刷题笔记22——求排序后数组相邻两数最大差值

题目描述 给定一个数组, 求如果排序之后, 相邻两数最大差值, 要求时间复杂度O(N), 且要求不能用非基于比较的排序。 解法1:暴力法 题目要求时间复杂度为O(N),这意味着我们不能用基于比较的排序方法对数组做排序,因为最快也是O(NlogN)的,但还是做了一下。 方法就是排序了之后用后一个数减前一个数,更新maxGap的值就好了 解法2:利用桶的思想但不排序 这里,数组有N个数,就分N+1...

CSDN_dzh的博客 968

对一个数组排序之后求相邻数的最大差值

题目: 给定一个整形数组arr,返回排序后的相邻两数最大差值。 时间复杂度为O(N)。 解答: 如果用排序法实现,其时间复杂度为O(NlogN),而如果利用桶排序的思想(不是桶排序),可以做到O(N),额外空间复杂度为O(N)。遍历arr找到最大值max和最小值min。如果arr的长度为N,准备N+1个桶,把max单独放在第N+1个桶中,[min,max)范围上的数放在1N号桶里,对于1N号桶中...

dream_follower的博客 2226

一个无序实数数组中的相邻两个元素最大差值(实数桶排序

题目描述 求解数组元素在实轴上相邻的2个数之间的最大差值 输入   第一行输入一个正整数N,表示数据的个数   接下来的一行中有N个实数,表示数组中的N个元素,中间以空格分隔 输出:   实轴上相邻的两元素之间差值最大值 样例输入:    5    2.1  3.1  7.5  1.5  6.3 样例输出:    3.2 要求: 分析所写算法的时间复杂度,如果可能,考虑...

vocaloid01的博客 1992

相邻两数最大差值

问题:给定一个数组,求如果排序之后,相邻两数最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序。 分析: 如果数组有N个数,则用N+1个桶,加入有数组{5,78,40,30,95},N+1个桶的目的是排除最大差值是在同一个桶中产生,n+1个桶的话至少有一个空桶,但不能说明最大差值位于空桶的左右两个非空桶的之间的差值最大差值相邻两个非空桶,前一个桶的max和后一个桶的min相差...

Cheng 411

排序17:相邻两数最大差值

排序17:相邻两数最大差值

小菜鸟也想飞的博客 1626

如何得出数组里最大_相邻两数最大差值(超巧妙解法)

题目:给定一个数组,求如果排序之后,相邻两数最大差值,要求时间复杂度O(N),且不能用非基于比较的排序解法:首先,输入的数组是还没有排好序的,题目要求是不能使用非基于比较的排序而且排序算法的时间复杂度最低都要O(NlogN),这不符合题目要求的时间复杂度O(N),所以我们不能用普通的排序算法去解决该问题。要做到时间复杂度为O(N),那么第一时间想到的就是遍历数组的时候只会对数组遍历一趟。这里给大...

weixin_39638012的博客 1834

数组相邻两数最大差值

给定一个数组,求排序之后,相邻两数最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。 思路:因为要求时间复杂度为O(n)且不能用非比较排序,常用的比较排序很难做到O(n)。这里是借助n+1个桶,将n个数平均分配到n个桶里,所以我们所求的最大差值肯定不在一个桶内(只有一个数另说),然后依次求出当前桶最小值与前一个非空桶最大值的差值,求出最大差值就是我们要的结果。 st...

种一棵树最好的时间是十年前,其次是现在。 605

求数组相邻两数最大差值

给定一个数组,求如果排序之后,相邻两数最大差值,要求时间复杂度O(N)O(N)O(N),且要求不能用非基于比较的排序 import java.util.Arrays; /** * 求给定数组排序之后相邻两数最大差值,要求时间复杂度为O(N) */ public class MaxGap { public static int maxGap(int[] arr) { ...

跑码场 4187

无序数组排序后,求相邻两数之间的最大差值,代码过程详解

题目: 给定一个数组,求排序之后,相邻两数之间的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。 示例: 例如:3 1 6 2 7 排序之后 : 1 2 3 6 7 则相邻最大差值为3(6-3=3) 解法: 1.循环数组,找到最小值和最大值。 2.若有N个数,就创建N+1个桶来装数,分别为 0号桶,1号桶,2号桶......N号桶。 ...

小树的博客 2761

求数组相邻元素差值最大值快速算法(C++版)

题目: 整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数最大差值。 给定一个int数组A和A的大小n,请返回最大差值。保证数组元素多于1个。 思路: 基于桶排序思想 n个数 n+1个桶 最后一个桶存最大数 那么最大差值一定在非空桶的相邻2个桶之间 且=(空桶右边 min - 空桶左边max) 算法复杂度: 时间复杂度:O(n) 空

decode 6841

全志A133的AndroidSDK

本小节来学习如何下载全志安卓SDK,SDK的目录,编译和烧录提示:以下是本篇文章正文内容,下面案例可供参考以上就是整个SDK的目录和编译烧录,目的在于让初学者快速了解整个源码的目录和编译出镜像喜欢就订阅吧。

qq_24093081的博客 3993

OpenCV实现“全能扫描王”的图像矫正功能

相信很多人手机里都装了个“扫描全能王”APP,平时可以用它来可以扫描一些证件、文本,确实很好用。其实使用OpenCV也能实现“全能扫描王”的图像矫正功能,源码完整,欢迎下载学习。

上一篇: 最短排序子数组
下一篇: 判断tl树中是否有与t2树拓扑结构完全相同的子树
FreeeLinux
博客等级 码龄10年 421粉丝 356原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值