假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。
( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
請找出其中最小的元素。
你可以假設陣列中不存在重複元素。
示例 1:
輸入: [3,4,5,1,2]
輸出: 1
示例 2:
輸入: [4,5,6,7,0,1,2]
輸出: 0
思考
這題遍歷其實也能通過,但複雜度是o(n),有序,我們就可以用二分。
首先,檢查他有沒有反轉,沒有的話,最小值就是nums[0]。
如果反轉的話,我們需要找到反轉點的位置。
[7,8,1,2]反**生在8,1之間。
如果1當反轉點,那麼他前面的數比他大。
如果8當反轉點,那麼他後面的數比他小。
為什麼能用二分查詢?
1.我覺得首先基本有序
2.就是知道,二分之後,捨棄哪個區間。
首先讓mid = (left + right) /2
判斷mid是不是反轉點:
(下方紅色代表mid)
mid值1
mid值》mid+1值,返回mid+1 8,1
不然所小區間
如果mid值》left,說明對應的就是[3,4,5,6,7]這個大值遞增的區間,反轉值應該在右邊,left = mid +1
否則,對應的應該是類似這樣的[6,7,1,2,3,4],反轉值應該在左邊,right = mid -1
下面走一遍
首先左邊這個圖:
mid = 6,
mid>mid+1?,不大於
mid < mid -1?,不小於
所以縮小區間
mid > left ?大於,說明左邊都是遞增的,反轉點在右邊,left = mid +1
重新計算mid
現在mid > mid+1?大於,所以返回nums[mid+1] = 1
再看右邊
mid> mid +1? 不大於
mid < mid-1? 不小於
縮小區間
mid > left? 不大於,說明最小值在左邊,right = mid-1
重新計算mid
mid > mid+1嗎? 8>1,返回mid+1的值
**實現
/**
* @param nums
* @return
*/var findmin = function(nums)
let left = 0
let right = nums.length - 1
//檢查鍊錶是否反轉過
if (nums[left] < nums[right])
while(left <= right)
//2.小於前面乙個
if (nums[mid] < nums[mid-1])
//重新選新的中點,大於左邊,說明處於大的那個公升序,反轉點應該在右邊,left變大
if (nums[mid] > nums[left]) else }};
知識:1.二分查詢物件要是有序的表,而且你要知道縮小區間後可以捨棄哪一部分。 153和154 尋找旋轉排序陣列中的最小值
先找到有序的那一部分,然後有序那一部分中最左元素和min作比較。修改範圍,再次查詢。class solution left mid 1 else right mid 1 return min 看到題解的解法很簡潔。再次寫的時候發現體驗不太好。如果只比較兩端是比較不出啥的。如 8 1 2 3 4 8 ...
LintCode 尋找旋轉排序陣列中的最小值
1 尋找旋轉排序陣列中的最小值 假設乙個旋轉排序的陣列其起始位置是未知的 比如0 1 2 4 5 6 7 可能變成是4 5 6 7 0 1 2 你需要找到其中最小的元素。你可以假設陣列中不存在重複的元素。樣例 給出 4,5,6,7,0,1,2 返回 0 solution 本題可以直接使用蠻力法計算複...
LeetCode 尋找旋轉排序陣列中的最小值II
假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 請找出其中最小的元素。注意陣列中可能存在重複的元素。示例 1 輸入 1,3,5 輸出 1 示例 2 輸入 2,2,2,0,1 輸出 0 說明 這道題是 尋找旋轉排序陣...