leetcode 164. Maximum Gap 相邻元素的最大间隔 + 一个很好的桶排序示范

╰+哭是因爲堅強的太久メ 2022-06-08 07:25 272阅读 0赞

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.

这道题就是在一个无序的数组中寻找最大的相邻元素的Gap,最直接的方法就是先排序。然后遍历即可。

但是这不是本体的要求,我想了很久没想出来,看了网上的答案,才明白这道题考查的是桶排序,根据数组的最大值最小值的落差以及元素的数量,分配一定数量的桶,然后比较相邻桶的最小值和最大值(上一个桶的最大值和下一个桶的最小值一定是相邻的)就可以得出最大的相邻元素的Gap。

注意这道题是桶排序的一个很好的示范,很值得学习。

代码如下:

  1. import java.util.Arrays;
  2. /*
  3. * http://blog.csdn.net/tofu_jelly/article/details/43339305
  4. *
  5. * 借鉴桶排序
  6. *
  7. * */
  8. public class Solution
  9. {
  10. public int maximumGap(int[] nums)
  11. {
  12. if(nums==null || nums.length<=1)
  13. return 0;
  14. int maxNum=Integer.MIN_VALUE,minNum=Integer.MAX_VALUE;
  15. for(int i=0;i<nums.length;i++)
  16. {
  17. maxNum=Math.max(maxNum, nums[i]);
  18. minNum=Math.min(minNum, nums[i]);
  19. }
  20. if(nums.length==2)
  21. return maxNum-minNum;
  22. //元素之间的最大间隔,注意向上取整
  23. int averageGap = (int)Math.ceil((double)(maxNum-minNum)/(nums.length-1));
  24. //这个是处理元素都相等的情况
  25. if(averageGap==0)
  26. return 0;
  27. int numOfBuckets = (maxNum-minNum)/averageGap +1;
  28. int []minBuck=new int[numOfBuckets];
  29. Arrays.fill(minBuck, Integer.MAX_VALUE);
  30. int []maxBuck=new int[numOfBuckets];
  31. Arrays.fill(maxBuck, Integer.MIN_VALUE);
  32. //minBuck和maxBuch放的是对应的最大值和最小值
  33. for(int i=0;i<nums.length;i++)
  34. {
  35. int index=(nums[i]-minNum) / averageGap;
  36. minBuck[index] = Math.min(minBuck[index], nums[i]);
  37. maxBuck[index] = Math.max(maxBuck[index], nums[i]);
  38. }
  39. int maxGap = Integer.MIN_VALUE;
  40. //上一个桶的最大值和下一个桶的最小值肯定是相邻的,所以才可能存在最大的gap
  41. int pre=maxBuck[0];
  42. for(int i=0;i<numOfBuckets;i++)
  43. {
  44. //桶为空的情况
  45. if(minBuck[i]==Integer.MAX_VALUE && maxBuck[i]==Integer.MIN_VALUE)
  46. continue;
  47. else
  48. {
  49. maxGap=Math.max(maxGap,minBuck[i]-pre);
  50. pre=maxBuck[i];
  51. }
  52. }
  53. return maxGap;
  54. }
  55. /*
  56. * 使用排序做的答案
  57. * */
  58. public int maximumGapUseSort(int[] nums)
  59. {
  60. if(nums==null || nums.length<=1)
  61. return 0;
  62. Arrays.sort(nums);
  63. int maxGap=0;
  64. for(int i=1;i<nums.length;i++)
  65. maxGap=Math.max(nums[i]-nums[i-1], maxGap);
  66. return maxGap;
  67. }
  68. }

下面是C++的做法,这道题是桶排序的一个很好的应用

代码如下:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <climits>
  4. #include <vector>
  5. using namespace std;
  6. // 164. Maximum Gap
  7. class Solution
  8. {
  9. public:
  10. int maximumGap(vector<int>& nums)
  11. {
  12. if (nums.size() <= 1)
  13. return 0;
  14. int minNum = nums[0], maxNum = nums[0];
  15. for (int a : nums)
  16. {
  17. minNum = min(minNum, a);
  18. maxNum = max(maxNum, a);
  19. }
  20. if (nums.size() == 2)
  21. return maxNum - minNum;
  22. int averageGap = (int)ceil((double)(maxNum - minNum)/(nums.size()-1));
  23. if (averageGap == 0)
  24. return 0;
  25. int numBucks = (maxNum - minNum) / averageGap + 1;
  26. vector<int> minBuck(numBucks, numeric_limits<int>::max());
  27. vector<int> maxBuck(numBucks, numeric_limits<int>::min());
  28. for (int a : nums)
  29. {
  30. int index = (a - minNum) / averageGap;
  31. minBuck[index] = min(minBuck[index], a);
  32. maxBuck[index] = max(maxBuck[index], a);
  33. }
  34. int maxGap = numeric_limits<int>::min();
  35. int pre = maxBuck[0];
  36. for (int i = 0; i < numBucks; i++)
  37. {
  38. if (minBuck[i] == numeric_limits<int>::max()
  39. && maxBuck[i] == numeric_limits<int>::min())
  40. continue;
  41. else
  42. {
  43. maxGap = max(maxGap,minBuck[i] - pre);
  44. pre = maxBuck[i];
  45. }
  46. }
  47. return maxGap;
  48. }
  49. };

发表评论

表情:
评论列表 (有 0 条评论,272人围观)

还没有评论,来说两句吧...

相关阅读