408算法练习——寻找旋转排序数组中的最小值(数组)
寻找旋转排序数组中的最小值
原题链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/
一、问题描述
已知一个长度为 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 ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
示例 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 次旋转
二、问题分析
因为题目只要求找到数组中的最小值,所以我们只需要找到数组中的最小值即可,根据查找算法最优复杂度,我们应该尽可能让算法时间复杂度趋于logn。所以应该思考二分查找的解决方法。所以构思就是从数组首尾出发,不断的对数组进行二分,最后就能找出最小值。整个访问过程就像二叉树一样。
定义数组的首尾指针left和right,因为要找出数组元素中的最小值,分析数组就能发现对于最小值左侧从左到右遍历,元素值在递增;对于最小值右侧,从右到左遍历,元素值在递减;
为此我们可以对数组进行逻辑上的拆分,以最小值为界,由两端点向最小值靠近,最小值的左侧是一个递增序列,最小值的右侧是一个递减序列;
那么在取中间结点时就可以拿中间结点进行判断,如果中间结点值比左端点大,说明中间结点在上升序列上,说明最小值还在右边,此时放弃左侧结点;
如果中间结点值比右端点小,说明中间结点此时在递减序列上,最小值就在左边,此时放弃右边序列。
三、算法描述
代码:
注意:本题的 left + 1 ,要么是更大的值(升序),要么突然降序,掉到了最小值。所以无论如何,最小值还是包括在寻找范围内的。而右侧区域,如果草率就 right - 1 的话,可能就会错过最小值了
1 class Solution { 2 public int findMin(int[] nums) { 3 int left=0,right=nums.length-1; 4 while(left<right){ 5 int mid = left+(right-left)/2; 7 if(nums[mid] < nums[right]){ 8 right = mid; 9 }else{ 10 left = mid+1; 11 } 12 } 13 return nums[left]; 14 } 15 }

浙公网安备 33010602011771号