把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note:給出的所有元素都大於0,若陣列大小為0,請返回0。
思路
劍指offer中有這道題目的分析。這是一道二分查詢的變形的題目。
旋轉之後的陣列實際上可以劃分成兩個有序的子陣列:前面子陣列的大小都大於後面子陣列中的元素
注意到實際上最小的元素就是兩個子陣列的分界線。本題目給出的陣列一定程度上是排序的,因此我們試著用二分查詢法尋找這個最小的元素。
思路:(1)我們用兩個指標left,right分別指向陣列的第乙個元素和最後乙個元素。按照題目的旋轉的規則,第乙個元素應該是大於最後乙個元素的(沒有重複的元素)。
但是如果不是旋轉,第乙個元素肯定小於最後乙個元素。
(2)找到陣列的中間元素。
中間元素大於第乙個元素,則中間元素位於前面的遞增子陣列,此時最小元素位於中間元素的後面。我們可以讓第乙個指標left指向中間元素。
移動之後,第乙個指標仍然位於前面的遞增陣列中。
中間元素小於第乙個元素,則中間元素位於後面的遞增子陣列,此時最小元素位於中間元素的前面。我們可以讓第二個指標right指向中間元素。
移動之後,第二個指標仍然位於後面的遞增陣列中。
這樣可以縮小尋找的範圍。
(3)按照以上思路,第乙個指標left總是指向前面遞增陣列的元素,第二個指標right總是指向後面遞增的陣列元素。
最終第乙個指標將指向前面陣列的最後乙個元素,第二個指標指向後面陣列中的第乙個元素。
也就是說他們將指向兩個相鄰的元素,而第二個指標指向的剛好是最小的元素,這就是迴圈的結束條件。
到目前為止以上思路很耗的解決了沒有重複數字的情況,這一道題目新增上了這一要求,有了重複數字。
我們看一組例子:{1,0,1,1,1} 和 {1,1, 1,0,1} 都可以看成是遞增排序陣列{0,1,1,1,1}的旋轉。
這種情況下我們無法繼續用上一道題目的解法,去解決這道題目。因為在這兩個陣列中,第乙個數字,最後乙個數字,中間數字都是1。
第一種情況下,中間數字位於後面的子陣列,第二種情況,中間數字位於前面的子陣列。
因此當兩個指標指向的數字和中間數字相同的時候,我們無法確定中間數字1是屬於前面的子陣列(綠色表示)還是屬於後面的子陣列(紫色表示)。
也就無法移動指標來縮小查詢的範圍。
#include #include #include #include #include using namespace std;
class solution //if
int left = 0,right = size - 1;
int mid = 0;
// rotatearray[left] >= rotatearray[right] 確保旋轉
while(rotatearray[left] >= rotatearray[right])//if
mid = left + (right - left) / 2;
// rotatearray[left] rotatearray[right] rotatearray[mid]三者相等
// 無法確定中間元素是屬於前面還是後面的遞增子陣列
// 只能順序查詢
if(rotatearray[left] == rotatearray[right] && rotatearray[left] == rotatearray[mid])//if
// 中間元素位於前面的遞增子陣列
// 此時最小元素位於中間元素的後面
if(rotatearray[mid] >= rotatearray[left])//if
// 中間元素位於後面的遞增子陣列
// 此時最小元素位於中間元素的前面
else//else
}//while
return rotatearray[mid];
}private:
// 順序尋找最小值
int minorder(vector&num,int left,int right)//if
}//for
return result;
}};
int main();
//vectornum = ;
vectornum = ;
int result = s.minnumberinrotatearray(num);
// 輸出
cout<二分僅限於陣列沒有相同元素的時候,如果有相同元素只能遍歷陣列。(題目沒有說明「遞增」是指「非遞減」還是「嚴格遞增」)
更簡便的方法:
非遞減陣列旋轉之後最小值,也就是尋找分界點,分界點前後都是非遞減陣列,分界點後面的非遞減陣列比分界點前面的陣列都要小,因此對旋轉陣列按順序查詢,當出現後乙個數比前乙個小時,這個數就是最小值,若沒有出現後乙個數比前乙個數小的情況,這說明這個陣列所有的數都相等,返回陣列第乙個數即可。注意考慮陣列為空的情況,返回0
class solution
for (size_t i = 0; i < rotatearray.size()-1; i++)
return rotatearray[0];
}};
劍指Offer 6 旋轉陣列的最小元素
description把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。可以直接binary search,每次mid和r的...
Python劍指offer 旋轉陣列的最小數字
由旋轉陣列的定義可以知道,最小數字既要小於左邊的數又要小於右邊的數 另外因為陣列是非減排序的,所以陣列的原始狀態下一定是右邊的數大於中間的數大於左邊的數。利用二分查詢的思想,要想找到這個最小數說明順序陣列其中某個地方有個斷崖,所以旋轉陣列的最小數說明它是小於左邊的數的第乙個,也就是如果 rotate...
劍指offer 旋轉陣列的最小數
題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。public class test system.out.pr...