




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Java解決計(jì)算相鄰兩個(gè)數(shù)的最大差值的問(wèn)題hello,今天給大家?guī)?lái)一道算法題。這道算法題,是我目前為止,見過(guò)最難的一道題。那么到底是怎樣的一道算法題呢?如下:
題目:給定一個(gè)數(shù)組,求如果排序之后,相鄰兩數(shù)的最大差值。要求時(shí)間復(fù)雜度O(N),且要求不能用非基于比較的排序。
我查了一下,暫時(shí)沒有找到一個(gè)在線OJ的鏈接,只能自己寫一個(gè)對(duì)數(shù)器,手動(dòng)測(cè)試了。
當(dāng)初我看到這個(gè)題目的時(shí)候,說(shuō)這怎么可能呢?在一個(gè)無(wú)序的數(shù)組中,求相鄰兩個(gè)數(shù)據(jù)的最大差值??墒俏覀兌贾溃F(xiàn)在基于比較的排序算法,最快也只能夠達(dá)到O(N*logN)的水平,而題目明確限制時(shí)間復(fù)雜度要是O(N),所以想通過(guò)基于比較的排序,排序之后再進(jìn)行遍歷,時(shí)間復(fù)雜度肯定是達(dá)不到要求的。
有人可能也會(huì)想說(shuō),不是還有基于非比較的排序算法嗎?比如計(jì)數(shù)排序、基數(shù)排序、桶排序。但是題目又明確規(guī)定了不能使用基于非比較的排序算法。
這樣的話,想使用排序算法,進(jìn)行排序,這條路肯定是行不通的。只能另外想其他的辦法。
-------------------------------------------------------------------------------------------我是分割線-----------------------------------------------------------------------------------------
重頭戲來(lái)了?。?!整個(gè)代碼的流程如下:
1.先遍歷一遍數(shù)組,保存整個(gè)數(shù)組的最大值和最小值。
2.假設(shè)數(shù)組中一共有N個(gè)元素,那么我們就需要準(zhǔn)備N+1個(gè)桶。
這每一個(gè)桶里面,可以存儲(chǔ)一定范圍內(nèi)的數(shù)值,而具體可以存儲(chǔ)多大范圍內(nèi)的數(shù)值,需要用公式去計(jì)算。比如:第一個(gè)桶存儲(chǔ)0……9之間的數(shù),第二個(gè)桶存儲(chǔ)10……19的數(shù)……
3.我們?cè)俅伪闅v一遍數(shù)組,將每一個(gè)數(shù),放入到相應(yīng)的桶里。
解釋:為什么需要進(jìn)行以上這3個(gè)步驟???這是一個(gè)非常值得思考的問(wèn)題!??!
由題可知,一共有N個(gè)數(shù),但是我們準(zhǔn)備了N+1個(gè)桶。也就是說(shuō)我們將每個(gè)數(shù)放入相應(yīng)的桶中,就算這N個(gè)數(shù)都在各自的桶里,無(wú)論怎么放入,始終會(huì)多出來(lái)1個(gè)空桶。
而我們會(huì)根據(jù)一下這個(gè)公式,將每個(gè)數(shù)放入相應(yīng)的桶:(arr[i]-min)*N/(max-min)。
以上這個(gè)公式,就能夠計(jì)算出i位置的數(shù),應(yīng)該放入哪一個(gè)桶里。根據(jù)公式計(jì)算,最小值一定會(huì)放到第一個(gè)桶里,最大值也一定會(huì)放到最后一個(gè)桶里。那么既然第一個(gè)和最后一個(gè)桶肯定是有數(shù)據(jù)的,也就是說(shuō)明那個(gè)空桶肯定是中間的某一個(gè)桶。
正是因?yàn)檫@個(gè)空桶的存在,會(huì)將很多種計(jì)算的可能性直接抹殺掉。說(shuō)的具體點(diǎn),假設(shè)一個(gè)桶的存儲(chǔ)數(shù)的范圍是0~9,也就是這個(gè)桶能夠存儲(chǔ)10個(gè)數(shù),既然有一個(gè)空桶的話,那么肯定最后的答案是大于10的。
那么既然大于10的話,這兩個(gè)數(shù)肯定不會(huì)在同一個(gè)桶里。這樣的話,我們就排除了桶里面兩個(gè)數(shù)據(jù)的情況,只需要考慮相鄰兩個(gè)桶之間的數(shù),才可能是最終的答案。
就如上圖的形式,將所有的數(shù)據(jù)都放入相應(yīng)的桶里。因?yàn)橛锌胀暗拇嬖?,所以我們的答案必然是在兩個(gè)不同桶之間的數(shù)據(jù)進(jìn)行相減。而我們?cè)谶M(jìn)行相減的時(shí)候,只需要記錄每個(gè)桶的最大值和最小值即可。也就是說(shuō),用后一個(gè)桶的最小值,減前一個(gè)桶的最大值。以這樣的形式,循環(huán)N次,將每?jī)蓚€(gè)相鄰的桶進(jìn)行計(jì)算,就能得到最終的答案。
既然我們只需要每個(gè)桶里的最大值和最小值,那就準(zhǔn)備兩個(gè)數(shù)組maxs和mins,分別存儲(chǔ)即可。代碼如下:
以上就是這道題的所有代碼,代碼不多,但是其中的算法思想我覺得真的是很厲害,很難想象出,想到這個(gè)方法的是什么人。
核心就在于那個(gè)空桶的存在,抹殺很多的可能性。使其最終的答案只可能存在于相鄰兩個(gè)桶之間的數(shù)。
提問(wèn):假設(shè)給定的某一個(gè)數(shù)組,算出來(lái)桶的數(shù)據(jù)后,只有一個(gè)是空桶。那么最終的答案就一定是這個(gè)空桶右邊桶的數(shù)據(jù)減去左邊桶的數(shù)據(jù)嗎?
最后,我將整個(gè)代碼全部放到下面,包括了一個(gè)對(duì)數(shù)器,用于測(cè)試以上代碼的正確性。
importjava.util.Arrays;
publicclassCode01_CalcTwoNumDiv{
publicstaticvoidmain(String[]args){
inttestTime=5000;//測(cè)試次數(shù)
intN=50;//數(shù)組長(zhǎng)度
intrange=1000;//數(shù)據(jù)范圍
booleanflag=true;
for(inti=0;itestTime;i++){
int[]arr=generateArr(N,range);
intp1=calcTwoNumDiv(arr);
intp2=sortAfter(arr);
if(p1!=p2){
flag=false;
break;
System.out.println(flag"正確":"錯(cuò)誤");
publicstaticintcalcTwoNumDiv(int[]array){
if(array==null||array.length2){
return0;
intmax=Integer.MIN_VALUE;
intmin=Integer.MAX_VALUE;
for(inti:array){//先遍歷一遍數(shù)組,求最大值最小值
max=Math.max(max,i);
min=Math.min(min,i);
if(max==min){
return0;//如果最大值和最小值相等,說(shuō)明這個(gè)數(shù)組只有這一個(gè)數(shù)據(jù)
intlen=array.length;
boolean[]hasNum=newboolean[len+1];
int[]maxs=newint[len+1];
int[]mins=newint[len+1];
//遍歷數(shù)據(jù)
for(inti=0;iarray.length;i++){
intbit=getBit(array[i],len,max,min);//桶的位置
maxs[bit]=hasNum[bit]Math.max(maxs[bit],array[i]):array[i];//更新最大值
mins[bit]=hasNum[bit]Math.min(mins[bit],array[i]):array[i];//更新最小值
hasNum[bit]=true;//始終更新為true
//第一個(gè)桶和最后一個(gè)桶,肯定是有數(shù)據(jù)的。
intpreMax=maxs[0];
intres=Integer.MIN_VALUE;//最終的結(jié)果
for(inti=1;i=len;i++){
if(hasNum[i]){
res=Math.max(res,mins[i]-preMax);
preMax=maxs[i];//更新前一個(gè)的最大值
returnres;
publicstaticintgetBit(intnum,intlen,intmax,intmin){
return((num-min)*len)/(max-min);//計(jì)算num應(yīng)該存儲(chǔ)在哪個(gè)桶
publicstaticintsortAfter(int[]arr){
if(arr==null||arr.length2){
return0;
Arrays.sort(arr);
intres=Integer.MIN_VALUE;
for(inti=1;iarr.length;i++){
res=Math.max(res,arr[i]-arr[i-1
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 康復(fù)醫(yī)療考試題(含參考答案)
- 高級(jí)營(yíng)銷員試題庫(kù)(附參考答案)
- 遠(yuǎn)程辦公服務(wù)平臺(tái)租賃協(xié)議
- 農(nóng)業(yè)生產(chǎn)資料集中采購(gòu)合作協(xié)議
- 無(wú)人機(jī)飛航測(cè)繪合作協(xié)議
- 2023年計(jì)算機(jī)軟考考試模擬試題及答案
- 道交法試題及答案解說(shuō)
- 2025福建南平市供電服務(wù)有限公司招聘52人筆試參考題庫(kù)附帶答案詳解
- 2025江蘇亞威鑄造材料科技有限公司招聘41人筆試參考題庫(kù)附帶答案詳解
- 紡織品設(shè)計(jì)的供應(yīng)鏈管理方法試題及答案
- 美甲店工作分工合同協(xié)議
- 天一大聯(lián)考2024-2025學(xué)年(下)高三第二次四省聯(lián)考★物理+答案
- 2025天津東疆綜合保稅區(qū)管理委員會(huì)招聘10人筆試參考題庫(kù)附帶答案詳解
- 法院書記員招聘2023年筆試考試必做題有答案
- 2024年北京大興國(guó)際機(jī)場(chǎng)臨空經(jīng)濟(jì)區(qū)幼兒園招聘教師考試真題
- 《刑法學(xué)課件 》課件各章節(jié)內(nèi)容-第十章 共同犯罪
- 雅禮新苗杯試題及答案
- 2025神農(nóng)科技集團(tuán)有限公司第一批校園招聘17人(山西)筆試參考題庫(kù)附帶答案詳解
- 醫(yī)院地震安全培訓(xùn)
- 2025-2030中國(guó)低壓電器行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
- 2025上海海事大學(xué)輔導(dǎo)員考試題庫(kù)
評(píng)論
0/150
提交評(píng)論