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

2021-07-11 02:53:36 字數 4675 閱讀 8912

牛客oj:旋轉陣列的最小數字

九度oj:

github**: 008-旋轉陣列的最小數字

csdn題解:劍指offer–008-旋轉陣列的最小數字

牛客oj

九度oj

csdn題解

github**

旋轉陣列的最小數字

1386-旋轉陣列的最小數字

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

008-旋轉陣列的最小數字

您也可以選擇回到目錄–劍指offer–題集目錄索引

題目描述

把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減序列的乙個旋轉,輸出旋轉陣列的最小元素。

例如

陣列為的乙個旋轉,

該陣列的最小值為1。

最簡單的思想就是一趟迴圈找到最小的那個

#include 

#include

using

namespace

std;

// 除錯開關

#define __tmain main

#ifdef __tmain

#define dout cout

#else

#define dout 0 && cout

#endif // __tmain

class solution

int min = int_max;

for(int i = 0; i < rotatearray.size( ); i++)

}return min;

}};int __tmain( )

; vector

vec(a, a + 5);

solution solu;

cout

0;}

進一步我們發現,由於原序列基本有序,因此最大值後面那個就是最小值

#include 

#include

using

namespace

std;

// 除錯開關

#define __tmain main

#ifdef __tmain

#define dout cout

#else

#define dout 0 && cout

#endif // __tmain

class solution

}return rotatearray[0];

}};int __tmain( )

和二分查詢法一樣,用兩個指標分別指向陣列的第乙個元素和最後乙個元素。

我們注意到旋轉之後的陣列實際上可以劃分為兩個排序的子陣列,而且前面的子陣列的元素都大於或者等於後面子陣列的元素。我們還可以注意到最小的元素剛好是這兩個子陣列的分界線。

我們試著用二元查詢法的思路在尋找這個最小的元素

首先我們用兩個指標,分別指向陣列的第乙個元素和最後乙個元素。按照題目旋轉的規則,第乙個元素應該是大於或者等於最後乙個元素的(這其實不完全對,還有特例。後面再討論特例)。

接著我們得到處在陣列中間的元素

此時陣列中最小的元素應該位於該中間 元素的後面。我們可以把第一指標指向該中間元素,這樣可以縮小尋找的範圍。

按照上述的思路,我們的第乙個指標總是指向前面遞增陣列的元素,而第二個指標總是指向後面遞增陣列的元素。最後第乙個指標將指向前面子陣列的最後乙個元素, 而第二個指標會指向後面子陣列的第乙個元素。也就是它們最終會指向兩個相鄰的元素,而第二個指標指向的剛好是最小的元素。這就是迴圈結束的條件。

#include 

#include

using

namespace

std;

// 除錯開關

#define __tmain main

#ifdef __tmain

#define debug cout

#else

#define debug 0 && cout

#endif // __tmain

class solution

// 如果把排序陣列前面0個元素搬到後面,也就是說其實沒有旋轉,

// 那麼第0個元素就是最小的元素

// 因此我們將mid初始化為0

int mid = 0;

int low = 0, high = rotatearray.size( ) - 1;

if(rotatearray[low] < rotatearray[high])

mid = (low + high) / 2;

debug <", "

<", "

if(rotatearray[mid] >= rotatearray[low])

// 如果中間元素位於後面的遞增子陣列,那麼它應該小於或者等於第二個指標指 向的元素

else

if(rotatearray[mid] <= rotatearray[high])

}return rotatearray[mid];

}};int __tmain( )

; vector

vec(a, a + 5);

solution solu;

cout

0;}

我們考慮下特殊情況,我們的迴圈判斷是以rotatearray[low] >= rotatearray[high]為條件的,不滿足這個的特殊情況有那些呢?

由於是把遞增排序陣列前面的若干個資料搬到後面去,因此第乙個數字總是大於或者等於最後乙個數字,但按照定義還有乙個

特例:開始時就rotatearray[low] < rotatearray[high],那麼迴圈不會執行

如果把排序陣列前面0個元素搬到後面,也就是說其實沒有旋轉,

那麼第0個元素就是最小的元素

因此我們將mid初始化為0

現在可以了麼,有沒有特殊情況仍然未被處理的,

如果rotatearray[low] = rotatearray[high]

測試用例:

[1, 0, 1, 0, 1, 1]

對應輸出應該為:

你的輸出為:

此時

rotatearray[low] rotatearray[mid] rotatearray[high]三者相等

無法確定中間元素是屬於前面還是後面的遞增子陣列

只能順序查詢

因此我們的**如下

#include 

#include

using

namespace

std;

// 除錯開關

#define __tmain main

#ifdef __tmain

#define debug cout

#else

#define debug 0 && cout

#endif // __tmain

class solution

// 如果把排序陣列前面0個元素搬到後面,也就是說其實沒有旋轉,

// 那麼第0個元素就是最小的元素

// 因此我們將mid初始化為0

int mid = 0;

int low = 0, high = rotatearray.size( ) - 1;

if(rotatearray[low] < rotatearray[high])

mid = (low + high) / 2;

debug <", "

<", "

// 無法確定中間元素是屬於前面還是後面的遞增子陣列

// 只能順序查詢

if(rotatearray[low] == rotatearray[mid] && rotatearray[mid] == rotatearray[high])

// 如果該中間元素位於前面的遞增子陣列,那麼它應該大於或者等於第乙個指標指向的元素

if(rotatearray[mid] >= rotatearray[low])

// 如果中間元素位於後面的遞增子陣列,那麼它應該小於或者等於第二個指標指 向的元素

else

if(rotatearray[mid] <= rotatearray[high])

}return rotatearray[mid];

}private:

// 順序尋找最小值

int minorder(vector

&num, int low, int high)

//if

}//for

return result;

}};int __tmain( )

; vector

vec(a, a + 5);

solution solu;

cout

0;}

劍指offer008 跳台階

題目描述 乙隻青蛙一次可以跳上1級台階,也可以跳上2級。求該青蛙跳上乙個n級的台階總共有多少種跳法 先後次序不同算不同的結果 思路 若第一次跳1,則還剩f n 1 種跳法,若第一次跳2,則還剩f n 2 種跳法,斐波那契數列 class solution 遞迴,複雜度太高 def jumpfloor...

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

由旋轉陣列的定義可以知道,最小數字既要小於左邊的數又要小於右邊的數 另外因為陣列是非減排序的,所以陣列的原始狀態下一定是右邊的數大於中間的數大於左邊的數。利用二分查詢的思想,要想找到這個最小數說明順序陣列其中某個地方有個斷崖,所以旋轉陣列的最小數說明它是小於左邊的數的第乙個,也就是如果 rotate...

劍指offer 旋轉陣列的最小數

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