劍指Offer 旋轉陣列的最小數字

2021-09-29 03:56:23 字數 1634 閱讀 9844

如果面設題是要求在排序的陣列(或者部分排序的陣列)中查詢乙個數字或者統計某個數字出現的次數,那麼我們都可以嘗試使用二分法

**力扣:

方法一:二分法

只要是一次可以排除一半,都可以用二分法。那麼如何使用二分法呢?我們很自然會想到使用邊界的值和中間位置的值進行比較。

注意:這裡的提法是「中間數」,即位於中間的那個數,不是中位數,請注意區分。

可以分為以下兩種情況:

1、中間數與左邊界比較

嘗試在紙上寫出幾個例子:

例 1:[1, 2, 3, 4, 5]

例 2:[2, 3, 4, 5, 1]

以上這兩個例子,中間數都比左邊界大,但是旋轉排序陣列的最小值可能在中間數的左邊(例 1),也可能在中間數的右邊(例 2),因此不能使用中間數與左邊界比較作為二分法的討論依據。

接下來,看看另一種討論依據。

2、中間數與右邊界比較:

(1)當中間數比右邊界表示的數大的時候,中間數就一定不是目標數(旋轉排序陣列的最小值)。

還是嘗試舉個例子:

例 3:[7, 8, 9, 10, 11, 12, 1, 2, 3]

中間數 11 比右邊界 3 大,因此中間數以及中間數前面的數都不是目標數,把左邊界設定中間數字置 + 1,即 left = mid + 1;

(2)當中間數比右邊界表示的數小的時候,中間數就可能是目標數(旋轉排序陣列的最小值),舉個例子:

例 4:[7, 8, 1, 2, 3]

中間數 1 比右邊界表示的數小的時候,說明,中間數到右邊界是遞增的(對於這道題是非遞減),那麼中間數右邊的(不包括中間數)就一定不是目標數,可以把它們排除,不過中間數有可能是目標數,就如本例,因此,把右邊界設定為 right = mid。

(3)當中間數與右邊界表示的數相等的時候,看下面兩個例子:

例 5:[0, 1, 1, 1, 1, 1, 1]

例 6:[1, 1, 1, 1, 0, 1, 1]

目標值可能在中間數的左邊,也可能在中間數的右邊,那麼該怎麼辦呢?很簡單,此時你看到的是右邊界,就把只右邊界排除掉就好了。正是因為右邊界和中間數相等,你去掉了右邊界,中間數還在,就讓中間數在後面的迴圈中被發現吧。

因此,根據中間數和右邊界的大小關係,可以使用二分法搜尋到目標值。

思考:如果中間數大於最右面的數 說明最小的數在中間數和最右面數之間,因為陣列是排完序的 最左邊的元素肯定大於最右邊的數

package arrays;

public

classs6;

system.out.

println

(s6.

minnumberinrotatearray

(arr));

}public

static

intminnumberinrotatearray

(int

array)

else

if(array[mid]

== array[right]

)else

if(array[mid]

< array[right])}

return array[left];}

}

劍指offer 旋轉陣列的最小數

題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。public class test system.out.pr...

劍指offer 旋轉陣列的最小數字

題目 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個排好序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。分析 這道題最直觀的解法並不難。從頭到尾遍歷陣列一次,就能找出最小的元素,時間複雜度顯然是o n 但這個思路沒有利用輸入陣列的特性...

劍指offer 旋轉陣列的最小數字

記錄來自 劍指offer 上的演算法題。題目描述如下 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個選擇,輸出旋轉陣列的最小元素。例如陣列是的乙個旋轉,該陣列的最小值是1。這裡可以採用二分查詢的想法,使用兩個指標,乙個指向第乙個元素,乙個指向末尾元素,...