本文主要是介绍leetcode题:154. 寻找旋转排序数组中的最小值 II(困难),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、题目描述:154. 寻找旋转排序数组中的最小值 II(困难)
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
注意数组中可能存在重复的元素。
示例 1:
输入: [1,3,5]
输出: 1
示例 2:输入: [2,2,2,0,1]
输出: 0
说明:这道题是 寻找旋转排序数组中的最小值 的延伸题目。
允许重复会影响算法的时间复杂度吗?会如何影响,为什么?来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、解题思路
使用二分法,初始化左右指针left =0,right = nums.size()-1.
1)如果num[left] <nums[right]说明没有旋转,left的元素就是最小值。直接返回left元素。
2)一直二分法,mid = (left + right)/2寻找num[left] > nums[right]的区间(注意这里要保持right=mid或者left=mid,而不能right=mid-1.因为当mid的元素为最小值的时候right=mid-1的话会将最小值排除掉)。如果nums[left] > nums[mid] 则right =mid,如果nums[right] < nums[mid]则left=mid。由于存在重复的数字,当nums[left] == nums[mid] && nums[mid] == nums[right]的时候,right = right-1(因为此时最小值可能在mid左边,也可能在mid右边,无法确定,所有right一直往左偏移直到找到nums[left] > nums[right]的区间。特殊情况下时间复杂度为O(n)
直到left == mid ,则返回min(nums[left],nums[right])退出,当left == mid的时候说明right=left或者right=left+1.此时最小值必然在left或者right里面。
三、代码
class Solution {
public:int findMin(vector<int>& nums) {int left = 0;int right = nums.size()-1;if(nums[left] < nums[right])return nums[left];while(left <= right){int mid = (left + right)/2;if(left == mid){return min(nums[left],nums[right]);}if(nums[mid] < nums[left]){right = mid;}else if(nums[mid] > nums[right]){left = mid;}else{right--;;}}return nums[left];}
};
这篇关于leetcode题:154. 寻找旋转排序数组中的最小值 II(困难)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!