题目如下图所示

常见做法如题解所示。
class Solution {
public int findMin(int[] nums) {
int low = 0;
int high = nums.length - 1;
while (low < high) {
int pivot = low + (high - low) / 2;
if (nums[pivot] < nums[high]) {
high = pivot;
} else {
low = pivot + 1;
}
}
return nums[low];
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/solutions/698479/xun-zhao-xuan-zhuan-pai-xu-shu-zu-zhong-5irwp/
来源:力扣(LeetCode)
但也可以采用如下做法
class Solution {
public int findMin(int[] nums) {
int l = 0, r = nums.length - 1;
int mid;
while (l <= r) {
mid = (l + r) / 2;
if (nums[mid] < nums[0])
r = mid - 1;
else
l = mid + 1;
}
return nums[l % nums.length];
}
}
问题背景
该代码解决的是在旋转排序数组中寻找最小值的问题。旋转排序数组是指一个原本按升序排列的数组,在某个未知的点进行了旋转。例如,[0,1,2,4,5,6,7] 旋转后可能变为 [4,5,6,7,0,1,2]。
算法思路
代码采用二分查找法来高效地定位最小值。以下是算法的核心逻辑:
- 初始化指针:
l(左指针)初始化为0,r(右指针)初始化为nums.length - 1。 - 循环条件:
while (l <= r)确保区间有效时继续查找。 - 中间值计算:
mid = (l + r) / 2计算中间索引。 - 比较中间值与数组首元素:
- 如果
nums[mid] < nums[0],说明最小值在左半部分,调整右指针r = mid - 1。 - 否则,最小值在右半部分,调整左指针
l = mid + 1。
- 如果
- 返回结果:循环结束后,最小值位于
l % nums.length的位置,避免越界。
关键点解析
- 旋转特性:旋转后的数组分为两个有序部分,最小值位于第二个有序部分的起始点。
- 二分调整:通过比较中间值与数组首元素,可以确定最小值所在的区间。
- 边界处理:通过取模运算保证结果不越界,适用于所有旋转情况,包括未旋转的数组。
示例分析
以旋转数组 [4,5,6,7,0,1,2] 为例:
- 初始时
l = 0,r = 6,nums[0] = 4。 mid = 3,nums[3] = 7大于nums[0],调整左指针l = 4。mid = 5,nums[5] = 1小于nums[0],调整右指针r = 4。mid = 4,nums[4] = 0小于nums[0],调整右指针r = 3。- 循环结束,
l = 4,返回nums[4 % 7] = 0。
复杂度分析
- 时间复杂度:O(log n),二分查找每次将搜索范围减半。
- 空间复杂度:O(1),仅使用常数级别的额外空间。
334

被折叠的 条评论
为什么被折叠?



