链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
这道题首先要想明白,其实思路很简单,当数组旋转之后,从开始旋转的位置到最后一段的数,一定比最左边的数小,当然也一定比从最左边到旋转点的数小。比如[1,2]小于[3,4,5]。这个可以当作二段性。那么我们要找所有比最左边数小的数中的第一个。但是这样做会出现一个问题,当数组没有旋转的时候,这个性质就不存在了。所以要在前面加一个错判,没有旋转的时候直接返回原数组中的第一个数即可。
c++代码如下:
1 class Solution { 2 public: 3 int findMin(vector<int>& nums) { 4 if(nums.empty()) return nums.size(); 5 if(nums[nums.size() - 1] >= nums[0]) return nums[0]; 6 int n = nums[0]; 7 int l = 0, r = nums.size() - 1; 8 while(l < r){ 9 int mid = l + r >> 1; 10 if(nums[mid] <= n) r = mid; 11 else l = mid + 1; 12 } 13 return nums[r]; 14 } 15 };
有一种更简单的方法,可以省略错判的步骤,我们可以用所有小于旋转/未旋转数组中最后一个数作为性质,返回满足这个性质的第一个点。
c++代码如下:
1 class Solution { 2 public: 3 int findMin(vector<int>& nums) { 4 if(nums.empty()) return nums.size(); 5 int l = 0, r = nums.size() - 1; 6 while(l < r){ 7 int mid = l + r >> 1; 8 if(nums[mid] <= nums.back()) r = mid; 9 else l = mid + 1; 10 } 11 return nums[r]; 12 } 13 };
另外还有一个小tips,在c++中,数组的最后一个元素可以用nums.back()来表示,数组是否为空可以用nums.empty()来表示。