日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

程序员面试题精选100题(42)-旋转数组的最小元素[算法]

發(fā)布時間:2025/3/21 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员面试题精选100题(42)-旋转数组的最小元素[算法] 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目:把一個數(shù)組最開始的若干個元素搬到數(shù)組的末尾,我們稱之為數(shù)組的旋轉(zhuǎn)。輸入一個排好序的數(shù)組的一個旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。例如數(shù)組{3, 4, 5, 1, 2}{1, 2, 3, 4, 5}的一個旋轉(zhuǎn),該數(shù)組的最小值為1

?????????分析:這道題最直觀的解法并不難。從頭到尾遍歷數(shù)組一次,就能找出最小的元素,時間復(fù)雜度顯然是O(N)。但這個思路沒有利用輸入數(shù)組的特性,我們應(yīng)該能找到更好的解法。

?????????我們注意到旋轉(zhuǎn)之后的數(shù)組實際上可以劃分為兩個排序的子數(shù)組,而且前面的子數(shù)組的元素都大于或者等于后面子數(shù)組的元素。我們還可以注意到最小的元素剛好是這兩個子數(shù)組的分界線。我們試著用二元查找法的思路在尋找這個最小的元素。

?????????首先我們用兩個指針,分別指向數(shù)組的第一個元素和最后一個元素。按照題目旋轉(zhuǎn)的規(guī)則,第一個元素應(yīng)該是大于或者等于最后一個元素的(這其實不完全對,還有特例。后面再討論特例)。

接著我們得到處在數(shù)組中間的元素。如果該中間元素位于前面的遞增子數(shù)組,那么它應(yīng)該大于或者等于第一個指針指向的元素。此時數(shù)組中最小的元素應(yīng)該位于該中間元素的后面。我們可以把第一指針指向該中間元素,這樣可以縮小尋找的范圍。同樣,如果中間元素位于后面的遞增子數(shù)組,那么它應(yīng)該小于或者等于第二個指針指向的元素。此時該數(shù)組中最小的元素應(yīng)該位于該中間元素的前面。我們可以把第二個指針指向該中間元素,這樣同樣可以縮小尋找的范圍。我們接著再用更新之后的兩個指針,去得到和比較新的中間元素,循環(huán)下去。

按照上述的思路,我們的第一個指針總是指向前面遞增數(shù)組的元素,而第二個指針總是指向后面遞增數(shù)組的元素。最后第一個指針將指向前面子數(shù)組的最后一個元素,而第二個指針會指向后面子數(shù)組的第一個元素。也就是它們最終會指向兩個相鄰的元素,而第二個指針指向的剛好是最小的元素。這就是循環(huán)結(jié)束的條件。

基于這個思路,我們可以寫出如下代碼:

// Get the minimum number of a roatation of a sorted array int Min(int *numbers, int length) {if(numbers == 0 || length <= 0)throw new std::exception("Invalid parameters");int index1 = 0;int index2 = length - 1;int indexMid = index1;while(numbers[index1] >= numbers[index2]){if(index2 - index1 == 1){indexMid = index2;break;}indexMid = (index1 + index2) / 2;if(numbers[indexMid] >= numbers[index1])index1 = indexMid;else if(numbers[indexMid] <= numbers[index2])index2 = indexMid;}return numbers[indexMid]; }

由于我們每次都把尋找的范圍縮小一半,該算法的時間復(fù)雜度是O(logN)

值得注意的是,如果在面試現(xiàn)場寫代碼,通常我們需要用一些測試用例來驗證代碼是不是正確的,我們在驗證的時候盡量能考慮全面些。像這道題,我們出來最簡單測試用例之外,我們至少還需要考慮如下的情況:

1.??????????????把數(shù)組前面的0個元素從最前面搬到最后面,也就是原數(shù)組不做改動,根據(jù)題目的規(guī)則這也是一個旋轉(zhuǎn),此時數(shù)組的第一個元素是大于小于或者等于最后一個元素的;

2.??????????????排好序的數(shù)組中有可能有相等的元素,我們特別需要注意兩種情況。一是旋轉(zhuǎn)之后的數(shù)組中,第一個元素和最后一個元素是相等的;另外一種情況是最小的元素在數(shù)組中重復(fù)出現(xiàn)

3.??????????????在前面的代碼中,如果輸入的數(shù)組不是一個排序數(shù)組的旋轉(zhuǎn),那將陷入死循環(huán)。因此我們需要跟面試官討論是不是需要判斷數(shù)組的有效性。在面試的時候,面試官討論如何驗證輸入的有效性,能顯示我們思維的嚴密性。本文假設(shè)在調(diào)用函數(shù)Min之前,已經(jīng)驗證過輸入的有效性了。

最后需要指出的是,如果輸入的數(shù)組指針是非法指針,我們是用異常來做錯誤處理。這是因為在這種情況下,如果我們用return來結(jié)束該函數(shù),返回任何數(shù)字都不是正確的。關(guān)于無效輸入時的函數(shù)如何返回錯誤信息并結(jié)束,本博客第17有更詳細的討論,可以參考。

?

本文已經(jīng)收錄到《劍指Offer——名企面試官精講典型編程題》一書中,有改動,書中的分析講解更加詳細。歡迎關(guān)注。

本題已被九度Online Judge系統(tǒng)收錄,歡迎讀者移步到http://ac.jobdu.com/hhtproblems.php在線測試自己的代碼。


博主何海濤對本博客文章享有版權(quán)。網(wǎng)絡(luò)轉(zhuǎn)載請注明出處http://zhedahht.blog.163.com/。整理出版物請和作者聯(lián)系。

總結(jié)

以上是生活随笔為你收集整理的程序员面试题精选100题(42)-旋转数组的最小元素[算法]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。