1. 题目来源
链接:寻找旋转排序数组中的最小值
来源:LeetCode
2. 题目说明
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
3. 题目解析
方法一:二分法
主要思想如下:
- 用中间的值
nums[mid]
和右边界值nums[right]
进行比较 - 若数组没有旋转或者旋转点在左半段时,中间值是一定小于右边界值,所以要去左半边继续搜索,反之则去右半段查找
- 最终返回
nums[right]
即可
参见代码如下:
// 执行用时 :12 ms, 在所有 C++ 提交中击败了42.40%的用户
// 内存消耗 :12.5 MB, 在所有 C++ 提交中击败了5.37%的用户
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[right])
left = mid + 1;
else
right = mid;
}
return nums[right];
}
};
方法二:分治法、递归
主要思想如下:
- 每次将区间
[start, end]
从中间mid
位置分为两段,分别调用递归函数,并比较返回值,每次取返回值较小的那个即可
参见代码如下:
// 执行用时 :8 ms, 在所有 C++ 提交中击败了42.40%的用户
// 内存消耗 :12.7 MB, 在所有 C++ 提交中击败了5.37%的用户
class Solution {
public:
int findMin(vector<int>& nums) {
return helper(nums, 0, nums.size() - 1);
}
int helper(vector<int>& nums, int start, int end) {
if (nums[start] <= nums[end])
return nums[start];
int mid = (start + end) / 2;
return min(helper(nums, start, mid), helper(nums, mid + 1, end));
}
};