如何得出数组里最大_相邻两数的最大差值(超巧妙解法)
題目:
給定一個數(shù)組,求如果排序之后,相鄰兩數(shù)的最大差值,要求時間復雜度O(N),且不能用非基于比較的排序
解法:
首先,輸入的數(shù)組是還沒有排好序的,題目要求是不能使用非基于比較的排序而且排序算法的時間復雜度最低都要O(NlogN),這不符合題目要求的時間復雜度O(N),所以我們不能用普通的排序算法去解決該問題。要做到時間復雜度為O(N),那么第一時間想到的就是遍歷數(shù)組的時候只會對數(shù)組遍歷一趟。
這里給大家介紹一種非常巧妙的算法解決該問題。
假如數(shù)組中有n個數(shù),遍歷一遍數(shù)組得到數(shù)組中的最大值my_max,最小值my_min,然后我們?yōu)檫@n個數(shù)準備n+1個桶來裝這n個數(shù)。
如我們的輸入數(shù)組中有9個數(shù),遍歷一遍數(shù)組后得到數(shù)組中的最小值my_min和最大值my_max.
然后再從頭開始遍歷數(shù)組,數(shù)組中的最小值一定進入0號桶,數(shù)組中的最大值一定進入9號桶,數(shù)組中的其他元素也依次進桶.
現(xiàn)在有一個很重要的結論,那就是,9個數(shù),10個桶,遍歷完一輪數(shù)組之后,其中第一個桶和最后一個桶一定不為空,而且,中間的桶必定至少有一個桶是空桶!
還是用上述提到的例子,假設每一個桶內的元素都是按從小到大排好序的,而且0~9號桶也是按從小到大排好序(1號桶里的元素比0號桶里的元素都大,2號桶里的元素比1號桶里的元素都大),所以整個數(shù)組就可看成是排好序的。因為空桶的存在,相鄰兩數(shù)的最大差值有如下的情況。
1.桶內相鄰兩數(shù)的最大差值
可以看出,一個桶內的相鄰最大差值最大也就可能是9-0=9.
2.桶間相鄰兩數(shù)的最大差值(中間無空桶)
可以看出,桶間相鄰兩數(shù)的最大差值(中間無空桶)的最大差值的范圍是1~19.
3.桶間相鄰兩數(shù)的最大差值(中間有空桶)
可以看出,桶間相鄰兩數(shù)的最大差值(中間有空桶)的最大差值的范圍是10~29.正是中間有空桶的存在,就完美排除掉了第1種情況(桶內相鄰兩數(shù)的最大差值),也即,排好序的數(shù)組中的兩數(shù)最大差值,那兩個數(shù)絕對不可能在一個桶內!
所以,排序后數(shù)組的相鄰兩數(shù)最大差值出現(xiàn)的情況只可能是上面的情況2和情況3,因此只需要判斷相鄰兩個桶的相鄰兩數(shù)的最大即可,也即把所有桶都遍歷一遍,然后用該桶的最小值減去前一個非空桶的最大值(因為這樣才是數(shù)組排序后的相鄰兩個數(shù)),然后最后得出最大差值。
下面舉一個例子來說明整個算法的流程。
輸入一個數(shù)組[17, 0, 99, 23, 67, 13, 14, 89, 4],因為這個數(shù)組有9個數(shù),所以分配10個桶。
3.遍歷數(shù)組,依次入桶,記錄每個桶的最小值和最大值.入桶的算法為
,num為當前值,Len為數(shù)組長度,得到的結果為該num應該入幾號桶。
代碼:
class MaxGap {public:int maxGap(vector<int> nums){if (nums.size()<2)return 0;int len=nums.size();int my_min=INT_MIN;int my_max=INT_MAX;//找出最小值和最大值for (int i=0;i<len;i++){my_min=min(my_min,nums[i]);my_max=max(my_max,nums[i]);}if (my_min==my_max){return 0;}bool *hasNum=new bool[len+1];int *mins=new int[len+1];int *maxs=new int[len+1];int bid=0;for (int i=0;i<len;i++){//當前這個數(shù)應該去幾號桶bid=bucket(nums[i],len,my_min,my_max);//更新這個桶的最小值mins[bid]=hasNum[bid]?min(mins[bid],nums[i]):nums[i];//更新這個桶的最大值maxs[bid]=hasNum[bid]?max(maxs[bid],nums[i]):nums[i];hasNum[bid]=true;}//找到每個非空與前一個非空桶的最大差值int res=0;int lastMax=maxs[0];int i=1;for (;i<=len;i++){if (hasNum[i]){//相鄰兩個桶之間的最大差值比較,大的賦值給resres=max(res,mins[i]-lastMax);lastMax=maxs[i];}}return res;}//當前這個數(shù)應該去幾號桶int bucket(long num,long len,long my_min,long my_max){return (int) ((num-my_min)*len/(my_max-my_min));} }總結
以上是生活随笔為你收集整理的如何得出数组里最大_相邻两数的最大差值(超巧妙解法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: clr 面试_Java中高级面试题及答案
- 下一篇: 如何c51和mdk共存兼容_电磁兼容入门