若有 n 个元素,最大值为 max,最小值为 min,那么间距 t 最小为:( max - min ) / ( n - 1 )。
最关键的在于桶的大小。桶的大小是可以容纳的最大区间的范围,桶内实际区间范围大小等于桶内最大值减最小值,桶的大小 b 应该小于最小间距 t 且不小于 1 。比较相邻桶的时候,只需要比较前一个痛的最大值和后一个桶的最小值。桶的个数 k 为$⌈(max−min)/b⌉$。第 i 个桶保存的值区间为: $[min+i∗b, min+(i+1)∗b)$,由$\lfloor (num - min)/b$ 可以算出 num 属于哪个桶。
classBucket{ public: bool used=false; int min=INT_MAX; int max=INT_MIN; }; classSolution { public: intmaximumGap(vector<int>& nums){ int size=nums.size(); if(size<2)return0; int maxElem=*max_element(nums.begin(),nums.end()); int minElem=*min_element(nums.begin(),nums.end()); int bucketSize=max(1,(maxElem-minElem)/(size-1)); int bucketNum=(maxElem-minElem)/bucketSize+1; vector<Bucket> buckets(bucketNum); for(int i=0;i<size;i++) { int k=nums[i]; int index=(k-minElem)/bucketSize; buckets[index].used=true; buckets[index].min=min(k,buckets[index].min); buckets[index].max=max(k,buckets[index].max); } int maxGap=buckets[0].max-buckets[0].min; int lastMax=buckets[0].max; for(int i=1;i<bucketNum;i++) { if(buckets[i].used) { maxGap=max(buckets[i].min-lastMax,maxGap); lastMax=buckets[i].max; } } return maxGap; } };
intfindMin(vector<int>& nums){ int min=nums[0]; for(int i=1;i<nums.size();i++) min=min<nums[i]?min:nums[i]; return min; }
执行用时:8 ms, 在所有 C++ 提交中击败了93.60%的用户
内存消耗:12 MB, 在所有 C++ 提交中击败了92.74%的用户
暴力求解效率居然这么高??那还做个毛线。
还是要多学习:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
intfindMin(vector<int>& nums){ int left=0; int right=nums.size()-1; while(left<right) { int mid=(left+right)/2; if (nums[mid] > nums[right]) left = mid + 1; elseif(nums[mid] < nums[right]) right = mid; else right = right - 1 ; } return nums[left]; }