算法思想一:暴力法
解题思路:
主要通过对数组遍历获取最小值(此方法一般不推荐使用)
算法流程:
1、特殊情况,如果数组为空,则直接返回0
2、创建最小值 minx
3、遍历数组每一个元素num,并更新最小值 minx = min(minx,num)
4、遍历结束,直接返回 minx
代码展示:
Python版本
class Solution: def minNumberInRotateArray(self, rotateArray): # write code here # 暴力法 if len(rotateArray) == 0: return 0 # 构建最小值 minx = float('inf') # 循环遍历数组,获取最小值 for num in rotateArray: # 更新最小值 minx = min(minx, num) return minx
复杂度分析
时间复杂度O(N):N表示数组的长度,遍历整个数组O(N)
空间复杂度O(1):仅使用一个额外空间变量O(1)
算法思想二:二分法
解题思路:
排序数组的查找问题首先考虑使用 二分法 解决,其可将 遍历法 的 线性级别 时间复杂度降低至 对数级别
算法流程:
1、初始化: 声明 i, j 双指针分别指向 array 数组左右两端
2、循环二分: 设 m = (i + j) / 2 为每次二分的中点( "/" 代表向下取整除法,因此恒有 i≤m1、当 array[m] > array[j] 时: m 一定在 左排序数组 中,即旋转点 x 一定在 [m + 1, j] 闭区间内,因此执行 i = m + 1
2、当 array[m] < array[j] 时: m 一定在 右排序数组 中,即旋转点 x 一定在[i, m]闭区间内,因此执行 j = m
3、当 array[m] = array[j] 时: 无法判断 mm 在哪个排序数组中,即无法判断旋转点 x 在 [i, m] 还是 [m + 1, j] 区间中。解决方案: 执行 j = j - 1 缩小判断范围
3、返回值: 当 i = j 时跳出二分循环,并返回 旋转点的值 array[i] 即可。
2、当 array[m] < array[j] 时: m 一定在 右排序数组 中,即旋转点 x 一定在[i, m]闭区间内,因此执行 j = m
3、当 array[m] = array[j] 时: 无法判断 mm 在哪个排序数组中,即无法判断旋转点 x 在 [i, m] 还是 [m + 1, j] 区间中。解决方案: 执行 j = j - 1 缩小判断范围
3、返回值: 当 i = j 时跳出二分循环,并返回 旋转点的值 array[i] 即可。
图解:
代码展示:
class Solution: def minNumberInRotateArray(self, rotateArray): # write code here left = 0 right = len(rotateArray)-1 while left <=right: mid = (left+right)/2 if rotateArray[mid]>rotateArray[right]: left = mid +1 elif rotateArray[mid] <rotateArray[right]: right = mid else: right -=1 return rotateArray[mid]
复杂度分析
时间复杂度O(logN):N表示数组的长度,二分查找O(logN)
空间复杂度O(1):仅使用常数(i, j, m)额外空间变量O(1)
参考资料: