给定一个数组,求如果排序后,相邻两个元素的最大差值,要求时间复杂度为O(N)

第一种方法

计数排序后,然后找出两两之间的最大差值

计数排序的时间复杂度是O(N)

public class CountSort {

    public static void main(String[] args) {
        int[] arr = new int[] { 2, 5, 12, 8, 6, 90, 34, 10, 10 };
        sort(arr);
        Arrays.stream(arr).forEach(x -> System.out.print(x + " "));
        //计算出相邻两个元素的最大差值
        int maxGap = Integer.MIN_VALUE;
        for(int i = 1 ;i<arr.length ; i++) {
            int gap = arr[i]-arr[i-1];
            if(gap > maxGap) {
                maxGap = gap;
            }
        }
        System.out.println();
        System.out.println(maxGap);
    }

    public static void sort(int [] arr ) {
        //获取最大值和最小值
        int min = arr[0];
        int max = arr[0];
        for ( int i = 0; i < arr.length; i++) {
            if(arr[i] < min) {
                min = arr[i];
            }
            if(arr[i] > max) {
                max = arr[i];
            }
        }
        //初始化一个桶,并向桶里装数据
        int [] bucket = new int[max-min+1];
        for(int j=0 ; j<arr.length; j++) {
            bucket[arr[j]-min]++;
        }
        //从桶里取数据,将原数组排序
        int index = 0;
        for(int i =0 ;i <bucket.length;i++) {
            while(bucket[i]-- > 0) {
                arr[index++] = i+min;
            }
        }
    }

}

第二种方法:

1  使用桶的思想,设置N+1个桶,必然有一个空桶,那么就排除了最大差值在一个桶内,因为空桶两侧的差距肯定大于桶内的差距

2 但是最大差值不一定就是空桶左侧max和空桶右侧min,需要依次遍历求差值

public class MaxGap {

    public static void main(String[] args) {
        int[] arr = new int[] { 2, 5, 12, 8, 6, 90, 34, 10, 10 };
        int res = getMaxGap(arr);
        System.out.println(res);
    }

    public static int getMaxGap(int [] nums) {
        //获取最大值和最小值
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            min = Math.min(min, nums[i]);
            max = Math.max(max, nums[i]);
        }
        if (min == max) {
            return 0;
        }
        //假如原数组有N个元素,声明三个长度都是N+1的数组,代表着N+1个桶,序号是从0到n
        boolean[] hasNum = new boolean[len + 1];
        int[] maxs = new int[len + 1];
        int[] mins = new int[len + 1];
        //遍历原数组,将数组中的元素分别放到这n+1个桶中
        int bid = 0;
        for (int i = 0; i < len; i++) {
            bid = bucket(nums[i], len, min, max);
            mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i];
            maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i];
            hasNum[bid] = true;
        }
        //遍历这n+1个桶,将非空桶的最小值和该桶的上一个非空桶的最大值比较,两者之差中的最大值即为所求
        int res = 0;
        int lastMax = maxs[0];
        for (int i = 1; i <= len; i++) {
            if (hasNum[i]) {
                res = Math.max(res, mins[i] - lastMax);
                lastMax = maxs[i];
            }
        }
        return res;
    }

    //计算桶的下标位置
    public static int bucket(long num, long len, long min, long max) {
        return (int) ((num - min) * len / (max - min));
    }
}

原文地址:https://www.cnblogs.com/moris5013/p/11625256.html

时间: 2024-10-29 19:10:01

给定一个数组,求如果排序后,相邻两个元素的最大差值,要求时间复杂度为O(N)的相关文章

在O(n)时间复杂度内求无序数组中任意两个元素的最大差值,以及存在的组数

题目描述: 求无序数组中任意两个元素的最大差值,以及存在最大差值的组别数. 输入: 输入包含两行,第一行输入一个整数n:第二行n个正整数,用空格隔开. 输出: 输出为一行,包含最大差值,以及存在组别数. 样例输入: 4 4  1  2  1 输出: 3  2 一种实现代码如下(Java版): 1 import java.util.Scanner; 2 /** 3 * 在O(n)时间复杂度内求无序数组中任意两个元素的最大差值,以及存在的组数 4 * @author JiaJoa 5 * 6 */

给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序

思路: 桶排序 N个数,设置 N+ 1 个桶,,一定有一个空桶,,为的是保证最大差值一定是不是出现在同一个桶中: 只要比较 非空桶 的最小值,与前一个 非空桶的最大值,求 最大的差值, 1 package my_basic; 2 3 import java.text.Bidi; 4 import java.util.Arrays; 5 6 public class MaxGap { 7 8 /*给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排

StringBuffer- 需求,给定一个数组,int [] arr = {44,33,55,66,88}变成[44, 33, 55, 66, 88]

package cn.StringBuffer; /* * * 需求,给定一个数组,int [] arr = {44,33,55,66,88}; * 变成[44, 33, 55, 66, 88] * * */ public class PinJie { public static void main(String[] args) { int [] arr = {44,33,55,66,88}; String str = pinjie(arr); System.out.println("拼接后的字

【笔试题-腾讯】给定一个数组a[N],我们希望构造数组b[N]

腾讯2012实习生笔试题(加分题): 给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]*a[1]*...*a[N-1]/a[i].在构造过程: a)不允许使用除法: b)要求O(1)空间复杂度和O(n)时间复杂度: c)除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量.对空间和全局静态变量等): 请用程序实现并简单描述. 题意应该不难理解,乍一看有点儿无从下手的感觉,思考后没有突破的话就想放弃了.看到网上其他同学也给出了解法,代码很简洁,但是理解起来不是

js实现随机选取[10,100)中的10个整数,存入一个数组,并排序。 另考虑(10,100]和[10,100]两种情况。

1.js实现随机选取[10,100)中的10个整数,存入一个数组,并排序. 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <script type="text/java

选取10-100之间的10个数字,存入一个数组,并排序

//选取10-100之间的10个数字,存入一个数组,并排序//实现该功能函数function randomNub(arr,len,min,max){ //如果给的长度大于取值范围,则超出提示 if(len>=(max-min)){ return "超过"+min+"-"+max+"之间的个数范围"+(max-min-1)+"个的总数"; } //从小到大排序,实现该数组的降序排列 if(arr.length>=le

剑指Offer(Java版)第四十题:在数组中的两个数字,如果前面一个数字大于后面的数字, 则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。 并将P对1000000007取模的结果输出。 即输出P%1000000007

/*在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007 */ import java.util.*; public class Class40 { public int InversePairs(int[] array){ int length = array.length; int P = 0; for(int i = 0; i < lengt

剑指Offer(Java版)第六十七题:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口, 他们的最大值分别为{4,4,6,6,6,5}。

/*给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}: 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4

算法学习(3)----求数组中大小最接近的两个元素的差

<算法设计与分析基础>习题1.2 第 9 题如下: 考虑下面这个算法,它求的是数值数组中大小最接近的两个元素的差. 算法: MinDistance(A[0..n-1]) //输入:数字数组 A[0..n-1] //输出:数组中两个大小相差最少的元素的差值 dmin <- ∞ for i <- 0 to n-1 do for j <- 0 to n-1 do if i≠j and |A[[i]-A[j]| < dmin dmin <- |A[i]-A[j]| ret