輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為陣列的乙個旋轉,該陣列的最小值為1。
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉,這本身沒什麼,但是如果旋轉前的陣列是乙個排序好的遞增陣列,旋轉陣列就會有一些比較有意思的特性。
上圖中是乙個原陣列與旋轉陣列,我們可以發現,旋轉陣列有兩個排序好的子串行和,我們要找的數值1(最小值)是兩個子串行的分界值,也是第二個子串行的第乙個值。
二分查詢演算法是個很常見的查詢演算法,照比與順序查詢,它的速度更快,時間複雜度可以降低到o(log2n),具體的思想是:
首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。所以二分查詢也叫作折半查詢。
但是二分查詢的使用有前提條件:
1.必須採用順序儲存結構;
2.必須按數值大小有序排列。
比如在中查詢4,首先陣列滿足二分查詢的前提,那麼先選定3,3<4,在右側子表選定4,4=4,那麼該陣列中含有4。
講道理的話,順序陣列發生了旋轉已經就不滿足二分查詢演算法的前提條件了,但是好在問題是旋轉陣列的最小數字,個人感覺這個理解很重要,本來二分查詢滿足前提條件的話適用於任意查詢,而該任務只是在旋轉陣列中找最小,所以只有改一改二分的規則,還是可以用的。
首先讓兩個指標分別指向旋轉陣列的第乙個位置(0)和最後乙個位置(4),此時兩個指標中間的數是5,5>3&&5>2,5比p1指向的數值(3)大,這說明中間的數值(5)在第乙個子串行中,那麼第二個子串行一定在5的右面,最小的數字是第二個子串行的第乙個數值,那麼也一定在5的後面,此時為了縮小查詢範圍,構建子串行,就可以把p1調整到中間位置(2):
此時兩個中間的數是1,1<5&&1<2,數值1比p2指向的數值(2)小,這說明中間數值(1)在第二個子串行中,那麼最小數值一定在該數值的左面或者就是它,此時為了縮小查詢範圍,就可以移動p2到之間位置:
p1與p2位置只差1,那麼此時p2指向的那個數就是最小數。
所以,傳統的二分查詢演算法是兩個指標在確定中間值,中間值與要查詢的數值比較,以決定哪個指標移動到中間值以構建子表,最終查詢結束的的條件是:
1.中間值與待查詢數值相等
2.子表不存在
而在這個任務中的二分查詢演算法為,兩個指標在確定中間值,中間值與兩個指標指向的數值對比,以確定哪個指標移動到中間值以構建子表,最終查詢結束的條件是:
兩個指標指向的位置相差為1,p2指向的數值為最小數字。
關鍵之處在於指標移動的規則,這與傳統的二分查詢目的相同,都是為了在一次查詢後縮小查詢範圍,所以規則就是,如果中間數字比p1指向的數字大(一般情況下一定比p2指向的大),那麼移動p1,如果中間數字比p2指向的小(一般情況下一定比p1指向的小),那麼移動p2。因為,p1永遠在指向第乙個子串行,p2永遠再指向第二個子串行,而第二個子串行中最大的數都會比第乙個子串行最小的數還要小,所以永遠在和p1比大,和p2比小!!!
上面的方法適用於所有的旋轉陣列嗎?顯然不是:
1.如果旋轉0或陣列長度的整數倍時,陣列依舊是遞增的,此時該方法並不適用,解決方案為,初始狀態下,如果p1指向的值小於p2,那麼陣列必然是順序遞增的:
2.如果旋轉陣列第乙個位置的數字,最後乙個位置的數字,中間數字三者相等,該方法並不適用,此時只能順序查詢:
//比大 移動p1
if(numbers[indexmid] >= numbers[index1])
index1 = indexmid;
//比小 移動p2
else
if(numbers[indexmid] <= numbers[index2])
index2 = indexmid;
}return numbers[indexmid];
}//順序查詢
int mininorder(int* numbers, int index1, int index2)
return result;
}1.上面的****於劍指offer,這套**在運算元組時並沒有用指標,可能是為了中間值的選取和退出條件更方便。
2.**如何處理陣列長度是偶數的情況?
indexmid =(index1 + index2) / 2;
直接取整,最後結果是一樣的,大家隨便舉個例子試一下就好了。 旋轉陣列最小數字
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列 為的乙個旋轉,該陣列的最小值為1。code int min int numbers,int length int low 0 int high length 1 in...
旋轉陣列最小數字
旋轉陣列最小數字 劍指offer 二分查詢 題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。解題思路 題目要求找到最小元素,第一反應是排序,但陣列基本有序直接排序浪費效能。結合資料的特點前半部分遞增,後半部分遞減,...
演算法 旋轉陣列的最小數字
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。請實現乙個函式,輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如,陣列 3,4,5,1,2 為 1,2,3,4,5 的乙個旋轉,該陣列的最小值為1。注 給出的所有元素都大於0,若陣列大小為0,請返回0。採用二分查詢解決...