当前位置:网站首页>Leetcode(154)——寻找旋转排序数组中的最小值 II
Leetcode(154)——寻找旋转排序数组中的最小值 II
2022-07-02 17:02:00 【SmileGuy17】
Leetcode(154)——寻找旋转排序数组中的最小值 II
题目
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:
- 若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
- 若旋转 7 次,则可以得到 [0,1,4,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 = [1,3,5]
输出:1
示例 2:
输入:nums = [2,2,2,0,1]
输出:0
提示:
- n == nums.length
- 1 1 1 <= n <= 5000 5000 5000
- − 5000 -5000 −5000 <= nums[i] <= 5000 5000 5000
- nums 原来是一个升序排序的数组,并进行了 1 1 1 至 n n n 次旋转
进阶:这道题与 寻找旋转排序数组中的最小值 类似,但 nums 可能包含重复元素。允许重复会影响算法的时间复杂度吗?会如何影响,为什么?
题解
方法一:二分查找
思路
旋转排序数组 n u m s nums nums可能 被拆分为 2 个排序数组 n u m s 1 , n u m s 2 nums1 , nums2 nums1,nums2,并且 n u m s 1 nums1 nums1 任一元素 > = n u m s 2 >= nums2 >=nums2 任一元素;因此,考虑二分法寻找此两数组的分界点 n u m s [ i ] nums[i] nums[i] (即第 2 个数组的首个元素)。
设置 leftleft, rightright 指针在 numsnums 数组两端,midmid 为每次二分的中点:
- 当 n u m s [ m i d ] > n u m s [ r i g h t ] nums[mid] > nums[right] nums[mid]>nums[right] 时, m i d mid mid 一定在第 1 个排序数组中, i i i 一定满足 m i d < i < = r i g h t mid < i <= right mid<i<=right,因此执行 l e f t = m i d + 1 left = mid + 1 left=mid+1;
- 当 n u m s [ m i d ] < n u m s [ r i g h t ] nums[mid] < nums[right] nums[mid]<nums[right] 时, m i d mid mid 一定在第 2 个排序数组中, i i i 一定满足 l e f t < i < = m i d left < i <= mid left<i<=mid,因此执行 r i g h t = m i d right = mid right=mid;
- 当 n u m s [ m i d ] = = n u m s [ r i g h t ] nums[mid] == nums[right] nums[mid]==nums[right] 时,是此题对比 153题 的难点(原因是此题中数组的元素可重复,难以判断分界点 ii 指针区间);
- 例如 [ 1 , 0 , 1 , 1 , 1 ] [1, 0, 1, 1, 1] [1,0,1,1,1] 和 [ 1 , 1 , 1 , 0 , 1 ] [1, 1, 1, 0, 1] [1,1,1,0,1],在 l e f t = 0 , r i g h t = 4 , m i d = 2 left = 0, right = 4, mid = 2 left=0,right=4,mid=2 时,无法判断 m i d mid mid 在哪个排序数组中。
- 我们采用使相同两端某一端移动下标直到新的 l l l 和 r r r 的值不相等,来解决此问题(即恢复二分性),证明:
- 此操作不会使数组越界:因为迭代条件保证了 right > left >= 0;
- 此操作不会使最小值丢失:假设 nums[right]nums[right] 是最小值,有两种情况:
- 若 n u m s [ r i g h t ] nums[right] nums[right] 是唯一最小值:那就不可能满足判断条件 n u m s [ m i d ] = = n u m s [ r i g h t ] nums[mid] == nums[right] nums[mid]==nums[right],因为
mid < right(left != right 且 mid = (left + right) // 2 向下取整)
;
代码实现
Leetcode 官方题解:
class Solution {
public:
int findMin(vector<int>& nums) {
int low = 0;
int high = nums.size() - 1;
while (low < high) {
int pivot = low + (high - low) / 2;
if (nums[pivot] < nums[high]) {
high = pivot;
}
else if (nums[pivot] > nums[high]) {
low = pivot + 1;
}
else {
high -= 1;
}
}
return nums[low];
}
};
我自己的:
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.size() == 1) return nums[0];
int l = 0, r = nums.size() - 1, mid;
// 减去重复值,恢复二段性,但是不能全删除,要保留同样数字至少1个(和 81 题不一样)
while(nums[l] == nums[r] && l < r) l++; // 避免[1,1]
while(l <= r){
mid = (l+r)/2;
if(nums[l] <= nums[r]) break;
else{
if(nums[mid] >= nums[l]) l = mid + 1; // 删除左区间
else r = mid; // 删除右侧区间
}
}
return nums[l];
}
};
复杂度分析
时间复杂度:恢复二段性处理中,最坏的情况下(考虑整个数组都是同一个数)复杂度是 O ( n ) O(n) O(n),而之后的找旋转点是「二分」,复杂度为 O ( l o g n ) O(log{n}) O(logn)。整体复杂度为 O ( n ) O(n) O(n) 的。
空间复杂度: O ( 1 ) O(1) O(1)
边栏推荐
- 再放宽!这些应届生,可直接落户上海
- C# 检测图片是否被旋转并修改到正真的旋转
- Laravel框架安装时遇到的坑
- Simulateur nightGod + application de test de capture de paquets Fiddler
- Pychar modify pep8 e501 line too long > 0 characters
- Wechat applet video sharing platform system graduation design completion (7) Interim inspection report
- Use dosbox to run the assembly super detailed step "suggestions collection"
- 铁塔安全监测系统 无人值守倾角振动监测系统
- 国金证券是国企吗?在国金证券开户资金安全吗?
- PR曲线和ROC曲线概念及其区别
猜你喜欢
Babbitt | metauniverse daily must read: can you buy a virtual anchor for 1000 yuan? Is this the live gospel of small businesses or "cutting leeks"
揭秘得物客服IM全链路通信过程
微信小程序视频分享平台系统毕业设计毕设(4)开题报告
Summary of fun free GM games
微信小程序视频分享平台系统毕业设计毕设(7)中期检查报告
初夏,开源魔改一个带击杀音效的电蚊拍!
SteamOS 3.3 Beta 发布,Steam Deck 中文键盘终于来了
Remember to use ternary expressions when switching transformations
Nm01 function overview and API definition of nm module independent of bus protocol
再放宽!这些应届生,可直接落户上海
随机推荐
exness深度好文:动性系列-黄金流动性实例分析(五)
Leetcode 面试题 16.15. 珠玑妙算
300+ documents! This article explains the latest progress of multimodal learning based on transformer
Qt官方示例:Qt Quick Controls - Gallery
UE4 draw a circle with spline
消除IBM P750小机上的黄色报警灯[通俗易懂]
Iframe nesting details
Enter a valid user name and password in the Microsoft LDAP configuration page, and enter a valid user name in the Microsoft LDAP configuration page
MySQL about only_ full_ group_ By limit
NM02-独立于总线协议的NM模块调用序列图及代码解释
Pychar modify pep8 e501 line too long > 0 characters
微信小程序视频分享平台系统毕业设计毕设(5)任务书
夜神模擬器+Fiddler抓包測試App
719. Find the distance of the number pair with the smallest K
微信小程序视频分享平台系统毕业设计毕设(7)中期检查报告
MySQL installation and configuration
微信核酸检测预约小程序系统毕业设计毕设(2)小程序功能
如何设置VSCode删除整行快捷键?
Leetcode interview question 17.01 Addition without plus sign
微信小程序视频分享平台系统毕业设计毕设(2)小程序功能