zoukankan      html  css  js  c++  java
  • [Leetcode] Maximum Gap

    Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

    Try to solve it in linear time/space.

    Return 0 if the array contains less than 2 elements.

    You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.

    Solution:

    http://cgm.cs.mcgill.ca/~godfried/teaching/dm-reading-assignments/Maximum-Gap-Problem.pdf

    由于要求时间和空间复杂度是O(n), 因此用Java自带的sort就不行了(因为STL函数的sort()的复杂度是O(nlogn))

    所以我们在思考得用一种线性的排序方法来做此题,那么,线性的排序算法有哪些呢?

    Answer: 计数排序,基数排序,桶排序。

    下面的code是利用桶排序来做的。

    假设有N个元素A到B。

    那么最大差值不会小于ceiling[(B - A) / (N - 1)],令bucket的大小len = ceiling[(B - A) / (N - 1)],初始化N-1个桶。

    对于数组中的任意整数K(只针对数组中非min,max的值来放入桶中),很容易通过算式loc = (K - A) / len找出其桶的位置,然后维护每一个桶的最大值和最小值

    由于同一个桶内的元素之间的差值至多为len - 1,因此最终答案不会从同一个桶中选择。

    对于每一个非空的桶p,找出下一个非空的桶q,则q.min - p.max可能就是备选答案。返回所有这些可能值中的最大值。

    public class Solution {
        public int maximumGap(int[] num) {
            if(num==null||num.length<2)
                return 0;
            if(num.length==2)
                return num[0]>num[1]?num[0]-num[1]:num[1]-num[0];
            int min=Integer.MAX_VALUE;
            int max=Integer.MIN_VALUE;
            for(int i:num){
                min=Math.min(min, i);
                max=Math.max(max, i);
            }
          
            int gapRange=(int) Math.ceil((double)(max-min)/(num.length-1));
            int[] bucketsMIN=new int[num.length-1];
            int[] bucketsMAX=new int[num.length-1];
            Arrays.fill(bucketsMIN, Integer.MAX_VALUE);
            Arrays.fill(bucketsMAX, Integer.MIN_VALUE);
            for(int i:num){
                if(i==min||i==max)
                    continue;
                int idx=(i-min)/gapRange;
                bucketsMIN[idx]=Math.min(bucketsMIN[idx], i);
                bucketsMAX[idx]=Math.max(bucketsMAX[idx], i);
            }
            int previous=min;
            
            int maxGap=Integer.MIN_VALUE;
            for(int i=0;i<num.length-1;++i){
                if(bucketsMAX[i]==Integer.MIN_VALUE&&bucketsMIN[i]==Integer.MAX_VALUE)
              //说明桶是空的  
    continue; maxGap=Math.max(maxGap, bucketsMIN[i]-previous); previous=bucketsMAX[i]; } maxGap=Math.max(maxGap, max-previous); return maxGap; } }
  • 相关阅读:
    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    11
    实战 迁移学习 VGG19、ResNet50、InceptionV3 实践 猫狗大战 问题
    tx2系统备份与恢复
    如何在Ubuntu 18.04上安装和卸载TeamViewer
    bzoj 3732 Network (kruskal重构树)
    bzoj2152 聪聪可可 (树形dp)
    牛客 216D 消消乐 (二分图最小点覆盖)
    牛客 197E 01串
    Wannafly挑战赛23
  • 原文地址:https://www.cnblogs.com/Phoebe815/p/4194932.html
Copyright © 2011-2022 走看看