• [LeetCode] 164. Maximum Gap


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

    Return 0 if the array contains less than 2 elements.

    Example 1:

    Input: [3,6,9,1]
    Output: 3
    Explanation: The sorted form of the array is [1,3,6,9], either
                 (3,6) or (6,9) has the maximum difference 3.

    Example 2:

    Input: [10]
    Output: 0
    Explanation: The array contains less than 2 elements, therefore return 0.

    Note:

    • You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
    • Try to solve it in linear time/space.

    最大间距。

    题意是给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。

    这道题由于要求是在线性时间和空间内解决,所以思路是桶排序。桶排序的具体做法如下,这里的桶排序跟其他题目涉及到的桶排序/计数排序是不同的,这里我们是试图要把元素放入每一个桶但是又想确保有一个bucket是空的。这个空的bucket的前一个bucket里的最大值和后一个bucket里的最小值的差值就是要求的最大差值。比如我们有 N 个元素,我们可以试图给 N + 1 个bucket,那么一定有一个bucket是空的。这个推论类似于抽屉原理。我们可以找这个空的bucket的左右两个邻居bucket来得到这个最大差值。

    所以具体的做法是,遍历input数组,得到数组中的最大值max和最小值min,此时我们可以得到桶的size = (int) Math.ceil((double) (max - min) / (len - 1))。这个公式我暂时不知道怎么推导,暂且当做结论记住。同时我们还需要两个长度为 len - 1 的数组来分别记录每个bucket里的最大值和最小值。

    再次遍历input数组,如果遇到min和max就跳过,因为他们是第一个bucket的最小值和最后一个bucket的最大值,第一个bucket左边没有bucket,最后一个bucket的右边也没有bucket,所以他们没有办法参与到res的计算中,可以跳过。桶的size得到之后,对于每一个元素,我们通过这个公式就知道应该把他放入哪个bucket了。放入之后同时记得更新这个桶内的最大值和最小值。

    int bucket = (num - min) / gap;

    最后遍历桶的最大值数组和最小值数组,记得单独处理min和第一个桶子里的最小值的差值以及max和最后一个桶子里的最大值的差值计算。

    时间O(n) - required

    空间O(n)

    Java实现

     1 class Solution {
     2     public int maximumGap(int[] nums) {
     3         // corner case
     4         if (nums == null || nums.length < 2) {
     5             return 0;
     6         }
     7         // normal case
     8         int len = nums.length;
     9         int min = nums[0];
    10         int max = nums[0];
    11         for (int num : nums) {
    12             min = Math.min(min, num);
    13             max = Math.max(max, num);
    14         }
    15         // bucket size
    16         int gap = (int) Math.ceil((double) (max - min) / (len - 1));
    17         int[] bucketMin = new int[len - 1];
    18         int[] bucketMax = new int[len - 1];
    19         Arrays.fill(bucketMin, Integer.MAX_VALUE);
    20         Arrays.fill(bucketMax, Integer.MIN_VALUE);
    21         for (int num : nums) {
    22             // 跳过最大值和最小值是因为最大值是最后一个bucket的上限,他的右边没有bucket了
    23             // 最小值是第一个bucket的下限,他的左边没有bucket了
    24             // 所以实际是没法参与到res的计算中的,所以直接就不放了
    25             if (num == min || num == max) {
    26                 continue;
    27             }
    28             int bucket = (num - min) / gap;
    29             bucketMin[bucket] = Math.min(num, bucketMin[bucket]);
    30             bucketMax[bucket] = Math.max(num, bucketMax[bucket]);
    31         }
    32 
    33         int res = 0;
    34         int pre = min;
    35         for (int i = 0; i < len - 1; i++) {
    36             if (bucketMin[i] == Integer.MAX_VALUE && bucketMax[i] == Integer.MIN_VALUE) {
    37                 continue;
    38             }
    39             res = Math.max(res, bucketMin[i] - pre);
    40             pre = bucketMax[i];
    41         }
    42         res = Math.max(res, max - pre);
    43         return res;
    44     }
    45 }

    LeetCode 题目总结

  • 相关阅读:
    将01字符串转换成数字的办法
    Codeforces Round #180 (Div. 2) AB
    CPU制作过程『转』
    向VECTOR的头部添加元素
    母版页中js操作问题
    操作粘贴板
    XML和关系数据使用XML和数据集类
    XML和关系数据用XML加载数据集
    XPath和XSL转换向XML应用XSL转换
    XML和关系数据从XSD架构创建数据集映射
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13752780.html
Copyright © 2020-2023  润新知