1. 题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。
2. 解题思路
2.1 思路1
不使用条件“递增排序”,直接遍历数组,获取最小值。
2.2 思路2
不使用条件“递增排序”,直接遍历数组,当arr[i] > arr[i+1]时,表明arr[i+1]是该数组的最小值。
2.3 思路3
使用条件“递增排序”,使用二分查找。
3. 代码实现
3.1 思路1的代码实现
时间复杂度O(n),空间复杂度S(1)
class Solution:
def minArray(self, numbers):
"""
"""
if not numbers:
return
min_value = numbers[0]
for i in numbers:
if i < min_value:
return i
return min_value
3.2 思路2的代码实现
时间复杂度O(n),空间复杂度S(1)
class Solution:
def minArray(self, numbers):
"""
"""
if not numbers:
return
for i in range(len(numbers)-1):
if numbers[i] > numbers[i+1]:
return numbers[i+1]
return numbers[0]
3.3 思路3的代码实现
来源 leetcode 面试题11. 旋转数组的最小数字(二分法,清晰图解)
时间复杂度O(log2 n),空间复杂度S(1)
class Solution:
def minArray(self, numbers: [int]) -> int:
i, j = 0, len(numbers) - 1
while i < j:
m = (i + j) // 2
if numbers[m] > numbers[j]: i = m + 1 # m处的值大于j处的值,表明最小值在m的右边
elif numbers[m] < numbers[j]: j = m # m处的值小于j处的值,表明最小值在m的左边
else: j -= 1 # m处的值等于j处的值时,无法判断 m 在哪个排序数组中,j = j - 1缩小范围。
return numbers[i]
4. 总结
很明显,前两种解法并没有充分利用题目中的已知条件,所以在解题是要利用所有条件来思考。
5. 参考文献
[1] 剑指offer丛书