一【题目类别】
- 二分查找
二【题目难度】
- 中等
三【题目编号】
- 153.寻找旋转排序数组中的最小值
四【题目描述】
- 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
- 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
- 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
- 注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
- 给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
- 你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
五【题目示例】
-
示例 1:
输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。 -
示例 2:
输入:nums = [4,5,6,7,0,1,2]
输出:0
解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。 -
示例 3:
输入:nums = [11,13,15,17]
输出:11
解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
六【题目提示】
- n == nums.length
- 1 <= n <= 5000
- -5000 <= nums[i] <= 5000
- nums 中的所有整数 互不相同
- nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转
七【解题思路】
- 主要还是二分查找的思路
- 但是要判断数组右边的值,因为我们要找最小值,首先判断数组中间值是否小于数组右边界,如果小于的话,右边界值更新为数组中间值索引,因为右边界值比中间值大,那么最小值肯定不在右边,所以要向左边搜索,而且右边界值更新为数组中间值索引的目的是,有可能数组中间值就是最小的,先保存下来
- 如果中间值大于或等于数组右边界,那么最小值肯定在右边,向右搜索即可
- 最后返回数组左边界索引指向的值即可,这时候肯定是最小值,因为是右边(较大值)收缩过来的
八【时间频度】
- 时间复杂度: O ( l o g 2 N ) O(log_{2}N) O(log2N),其中 N N N为数组长度
- 空间复杂度: O ( 1 ) O(1) O(1)
九【代码实现】
- Java语言版
package BinarySearch;
public class p153_FindTheMinimumValueInARotatedSortedArray {
public static void main(String[] args) {
int[] nums = {3, 4, 5, 1, 2};
int res = findMin(nums);
System.out.println("res = " + res);
}
public static int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < nums[right]) {
right = mid;
} else {
left = mid + 1;
}
}
return nums[left];
}
}
- C语言版
#include<stdio.h>
int findMin(int* nums, int numsSize)
{
int left = 0;
int right = numsSize - 1;
while (left < right)
{
int mid = left + (right - left) / 2;
if (nums[mid] < nums[right])
{
right = mid;
}
else
{
left = mid + 1;
}
}
return nums[left];
}
/*主函数省略*/
十【提交结果】
-
Java语言版
-
C语言版