這道題是上一道題:33. 搜索旋轉排序數組的前置題,有點沒看懂力扣為什么要這樣安排題目順序,應該把這道題按排在前面才對啊。。。這道題的思路已經在上一道題的思路中說過了,這里就直接復制粘貼上一篇博客中的內容了。
我們閱讀完題目不難看出,經過旋轉后,數組nums
有兩種可能的狀態:
nums
被分為兩個局部有序的子數組,每一個子數組都是嚴格遞增的,此時第一個數組中的所有值均大于第二個數組中的最大值;nums
依舊保持整體有序
因此我們需要利用二分查找來判斷,定義left = 0
,right = nums.size() - 1
,使用左閉右開的搜索范圍([left, right)
),注意,此時nums
的最后一個元素始終都不在查找范圍內,因為我們需要不斷將中間值與num
最后一個元素進行比較,以確定最小值與中間值的位置關系。
1.當nums[mid] > nums.back()
時,說明mid
此時一定在第一個數組中,因為nums[mid]
比第二個數組的最大值都更大,不可能落在第二個數組中,此時數組的最小元素一定在mid
的右邊,此時我們更新搜索區間的左邊界,left = mid + 1
2.當nums[mid] <= nums.back()
時,說明mid
此時一定在第二個數組中,因為nums.back()
比第一個數組的任意元素都更小,而nums[mid]
比nums.back()
還小,不可能落在第一個數組,此時數組的最小元素一定在mid
的左邊,此時我們更新搜索區間的右邊界,right = mid
我們使用一個while
循環來尋找最小元素的位置,由于我們采用的是左閉右開的查找方式,因此區間合法的條件是left < right
,當循環結束后left == right
,此時nums[left]
或者nums[right]
都是最小值。
class Solution {
public:int findMin(vector<int>& nums) {int left = 0, right = nums.size() - 1; //[left, right)int mid;while(left < right){mid = (left + right) / 2;if(nums[mid] > nums.back()) //最小值在mid的右邊left = mid + 1;else right = mid; //最小值在mid的左邊}return nums[left];}
};