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.

    问题:给定一个无序数组,找出数组排序后的相邻元素最大间隔。要求 O(n) 时间复杂度,O(n)空间复杂度

    解题思路:

    思路一:将所有数组全部排序,再一次遍历求得最大的相邻元素间隔值即可。但是排序算法的最小时间复杂度也需要 O(n*logn) ,无法满足要求。

    思路二:题目只需要求出最大相邻间隔,可以利用桶排序,避免求出全部元素大小顺序,而得到结果。时间复杂度降低为 O(n)。

    具体思路:

    • 将元素全部减去最小值,得到新的数组
    • 根据数组长度,创建同样大小的桶(数组表示),并根据数组的数值区间、数组长度得到单个桶的大小
    •   double bucketSize = (double)(maxv-minv) / (double)nums.size();
    • 根据元素大小,将元素放到对应的桶里面。数组中最大值,最小值应该分别在最左边、最右边的两个桶里面。
    •   int idx = newNums[i] / bucketSize;
    •   bucket[idx].push_back(newNums[i]);

    // 断言 : 最大间隔值为桶间间隔的最大值。

    // 断言证明:当每个桶都有值时,每个桶只有一个值,断言成立。当至少有一个桶为空时,因为最左边、最右边两个桶都有值,则最大间隔必然为桶间间隔,而不是桶内间隔,断言成立。

    • 去掉每个桶中最大值、最小值之外的其他值
    • 一次遍历求得最大桶间间隔,即为原题解。
     1     int maximumGap(vector<int>& nums) {
     2         
     3         if (nums.size() < 2) {
     4             return 0;
     5         }
     6         
     7         int maxv = nums[0];
     8         int minv = nums[0];
     9         for (int i = 0 ; i < nums.size(); i++) {
    10             maxv = max(maxv, nums[i]);
    11             minv = min(minv, nums[i]);
    12         }
    13     
    14         vector<int> newNums;
    15         for (int i = 0 ; i < nums.size(); i++) {
    16             newNums.push_back(nums[i] - minv);
    17         }
    18         
    19         vector<vector<int>> bucket(nums.size() + 1);
    20         
    21         double bucketSize = (double)(maxv-minv) / (double)nums.size();
    22         
    23         // maxv == minv 
    24         if (bucketSize == 0 ) {
    25             return 0;
    26         }
    27                 
    28         for (int i = 0 ; i < newNums.size(); i++) {
    29             int idx = newNums[i] / bucketSize;
    30             bucket[idx].push_back(newNums[i]);
    31         }
    32     
    33         for (int i = 0 ; i < bucket.size(); i++) {
    34             if (bucket[i].size() >= 2) {
    35                 int maxi = bucket[i][0];
    36                 int mini = bucket[i][0];
    37                 for (int k = 0 ; k < bucket[i].size(); k++ ) {
    38                     maxi = max(maxi, bucket[i][k]);
    39                     mini = min(mini, bucket[i][k]);
    40                 }
    41                 bucket[i] = {mini, maxi};
    42             }
    43         }
    44         
    45         int maxgap = 0;
    46         
    47         int lmaxi = (bucket[0].size() == 1) ?    bucket[0][0] : bucket[0][1];
    48         
    49         for (int i = 0 ; i < bucket.size(); i++) {
    50             if (bucket[i].size() == 0 ) {
    51                 continue;
    52             }
    53             int maxi;
    54             int mini;
    55             
    56             if (bucket[i].size() == 1) {
    57                 maxi = bucket[i][0];
    58                 mini = bucket[i][0];
    59             }else{
    60                 // size of bucket[i] shoud be 2;
    61                 
    62                 mini = bucket[i][0];
    63                 maxi = bucket[i][1];
    64             }
    65             
    66             if ((mini - lmaxi) > maxgap) {
    67                 maxgap = (mini - lmaxi);
    68             }
    69             lmaxi = maxi;
    70         }
    71                 
    72         return maxgap;
    73     }
  • 相关阅读:
    【转载】用XML和XSLT来生成静态的HTML页面
    【转载】Lambda表达式(Lambda Expressions)
    [转]打领带的十种方法
    读书笔记
    【转载】用手机的朋友进来看看吧,终身受益啊!!!
    SQL查询出重复出现的数据
    技巧三:字符串格式化
    【Vegas原创】页面自动跳转代码收集
    【Vegas原创】我写的一个安装windowsService的BAT
    【Vegas原创】ASP.NET读取Excel,并以邮件正文方式和附件方式发送实例
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5117672.html
Copyright © 2011-2022 走看看