把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。
輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。
例如陣列為的乙個旋轉,該陣列的最小值為1。
note:給出的所有元素都大於0,若陣列大小為0,請返回0。
(一般情況)(特例,前面0個元素搬到後面,即已經排好序的情況)
/ (特例,都可以看成遞增排序陣列的旋轉)
遍歷整個陣列找出其中最小的數,複雜度為o(n),這是最容易想到的方案,但這樣沒用到旋轉陣列的特性,肯定不行!!
本題考查二分查詢。旋轉之後的陣列實際上可以劃分成兩個有序的子陣列:前面子陣列的元素都大於後面子陣列中的元素,而且最小的元素剛好是這兩個子陣列的分界線。
和二分查詢一樣,用兩個指標分別指向陣列的第乙個元素和最後乙個元素。
找到陣列的中間元素,如果中間元素大於第乙個指標指向的元素,則中間元素位於前面的遞增子陣列,此時最小元素位於中間元素的後面,我們讓第乙個指標left指向該中間元素;如果中間元素小於第二個指標指向的元素,則中間元素位於後面的遞增子陣列,此時最小元素位於中間元素的前面,我們讓第二個指標right指向中間元素。
這樣查詢範圍會縮小到原來的一半,第乙個指標總是指向前面遞增陣列的元素,第二個指標總是指向後面的遞增陣列的元素。最終,第乙個指標將指向前面子陣列的最後乙個元素,而第二個指標會指向後面子陣列的第乙個元素(也就是最小的元素),即它們最終指向兩個相鄰的元素,迴圈結束。
classsolution ,l、m 和 h 指向的數都為 1,
//此時無法知道最小數字 0 在哪個區間。
if (nums[mid] == nums[l] && nums[mid] ==nums[r])
//這裡要跟右邊界r 比,因為當只有兩個數時(a,b)
//那麼mid肯定取l.當判斷條件l與mid比時,會出現與自身比情況 不好判斷
//例如 (1,3) 和 (3,1)
if (nums[mid] <=nums[r])
else
}return
nums[l];
}private
int minnumber(int nums, int l, int
r) }
return
min;
}}
note:
關於取中間值為什麼是left+(right-left)/2,而不是直接(right+left)/2?
答:第一種方式更穩定!!如果兩個數都很大,相加將導致溢位。
int x = 1999999998;int y = 1999999998;
int mid = (x+y) / 2;
int mid2 = x + (y-x) / 2;
system.out.println(mid);
//-147483650
system.out.println(mid2); //
1999999998
劍指offer 旋轉陣列的最小數字06
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。class solution defminnumberinrotatear...
劍指Offer06 旋轉陣列的最小數字
題意 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列 3,4,5,1,2 為 1,2,3,4,5 的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。思路根據旋轉陣列的定義...
劍指offer 06 旋轉陣列的最小數字
題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。note 給出的所有元素都大於0,若陣列大小為0,請返回0。時間限制 c c 3秒,其他語言6秒 空間限制 c c 64m,其他語言128m 題目示例 輸入 3,4...