解題 旋轉陣列的最小數字的高效解法(C 實現)

2021-07-29 17:39:48 字數 1630 閱讀 6017

一、題目描述

題目:把乙個陣列最開始的若干個元素搬到陣列的末尾,稱之為陣列的旋轉。輸入乙個非降序排序陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列是陣列的乙個旋轉,該陣列的最小值為1。

二、思路分析

當然,在這裡我們放棄遍歷陣列的方法,看能否利用旋轉陣列的特點找到乙個時間效率更優的演算法。

可以注意到旋轉之後的陣列實質上可以劃分為兩個排序的子陣列,而且前面的子陣列的元素都大於等於後面子陣列的元素,而且最小的元素剛好是這兩個子陣列的分界線。回想這種情況,可以發現在前面分享過的二分查詢演算法剛好可以實現o(log n)查詢這個最小元素。

找到陣列的中間元素,如果它位於前面的子陣列,那麼它應該大於或者等於第乙個指標指向的元素,此時陣列的最小元素應該在它之後。這樣把第乙個指標指向這個中間元素。顯然,移動後的第乙個指標仍然位於前面的子陣列。

如果中間元素位於後面的子陣列,那麼它應該小於或者等於第二個指標指向的元素,此時陣列的最小元素應該在它前面。這樣把第二個指標指向該中間元素。

按照上述二分查詢的思路,最終定義的兩個指標會指向兩個相鄰的元素,而第二個指標剛好指向最小的元素。這就是迴圈環終止的條件

三、邊界條件的考察

1)如果輸入的旋轉陣列「沒有旋轉」,即為某個非降序陣列本身,比如輸入的情況:這樣第乙個元素就是最小元素,可以直接返回,在**中我們可以把indexmid初始化為index1來達到目的。(見下述**)

2)如果index1和index2指向的兩個數相等,且它們中間的數字也相同的情況,如輸入陣列的乙個旋**此時無法通過移動指標來縮小查詢範圍了,故而只能採用順序查詢方式。

四、**實現

int minvalue(int

*numbers, int

length);

int mininorder(int

*numbers, int index1, int index2);

int minvalue(int

*numbers, int

length)

indexmid = (index1 + index2) / 2;

//邊界條件2的解決方法,順序查詢

if (numbers[index1] == numbers[index2] && numbers[index1] == numbers[indexmid])

//二分查詢移動指標

if (numbers[indexmid] >= numbers[index1])

index1 = indexmid;

else

if (numbers[indexmid] <= numbers[index2])

index2 = indexmid;

}return numbers[indexmid];

}int mininorder(int

*numbers, int index1, int index2)

return result;

}

注:以上內容為《劍指offer》學習筆記。

旋轉陣列最小數字

把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列 為的乙個旋轉,該陣列的最小值為1。code int min int numbers,int length int low 0 int high length 1 in...

旋轉陣列最小數字

旋轉陣列最小數字 劍指offer 二分查詢 題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。解題思路 題目要求找到最小元素,第一反應是排序,但陣列基本有序直接排序浪費效能。結合資料的特點前半部分遞增,後半部分遞減,...

旋轉陣列的最小數字

1.問題描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出該旋轉陣列的最小元素。例如陣列 3,4,5,1,2 為 1,2,3,4,5 的乙個旋轉,該陣列的最小值為1.來自 劍指offer 2.分析 首先我們可以看到原陣列為遞增排序的,並且以...