【发布时间】:2019-04-12 23:48:04
【问题描述】:
我正在研究一个困难但愚蠢的二分搜索问题并调试了几个小时。
Find Minimum in Rotated Sorted Array II
- 在旋转排序数组 II 中查找最小值
困难
假设一个按升序排序的数组在您事先未知的某个枢轴处旋转。
(即,
[0,1,2,4,5,6,7]可能变为[4,5,6,7,0,1,2])。找到最小的元素。
数组可能包含重复项。
示例 1:
Input: [1,3,5] Output: 1示例 2:
Input: [2,2,2,0,1] Output: 0注意:
- 这是Find Minimum in Rotated Sorted Array 的后续问题。
- 允许重复会影响运行时复杂度吗?如何以及为什么?
被广泛接受的答案需要 O(n) 时间,
class SolutionK:
def findMin(self, nums):
lo, hi = 0, len(nums)-1
while lo < hi:
mid = (hi +lo) // 2
if nums[mid] > nums[hi]:
lo = mid + 1
elif nums[mid] < nums[hi]:
hi = mid
else:
hi -= 1
return nums[lo]
# why not min(nums) or brute force
我认为这个问题可以通过回收数组来解决。
由于有重复,我们可以找到最右边的最大值,那么 max + 1 就是最小值。
#the mid
lo = 0
hi = len(nums)
mid = (lo+hi) // 2
mid = mid % len(nums)
和终止条件
if nums[mid-1] <= nums[mid] > nums[mid+1]: return mid as the peak.
很遗憾,我无法设计递减条件。
能否给点提示?
【问题讨论】:
-
最坏的情况是像 [1,1,1,1,1,0,1,1,1] 这样的旋转数组,需要 O(n) 搜索才能找到 0。
-
是的,3 个主要的不同案例 * 2 个位置:重复次数最多,重复次数最少,重复次数介于两者之间。两个位置:在边缘或中间重复。
-
是的,在最坏的情况下,这三个都需要蛮力 O(n) 搜索。数组末端的非重复项允许在少于 O(n) 的时间内解决问题。
-
O(n)是最差的时间,平均时间应该是O(logn)