寻找旋转排序数组中的最小值

📌 题目解析

题目:给定一个旋转排序数组 nums,其中无重复元素,要求找到数组中的最小值

旋转排序数组的特点

• 初始为递增排序数组,某个位置 k 进行了旋转。

• 旋转后,前 k 个元素移到了数组的后面,导致前大后小的变化。

• 例如:

原数组: [1, 2, 3, 4, 5, 6, 7]
旋转后: [4, 5, 6, 7, 1, 2, 3]  (最小值 1)

• 数组可以分成两个单调递增部分

左半部分:nums[left] >= nums[0]

右半部分:nums[right] <= nums[right-1]

🚀 二分查找思路

目标:利用 二分查找 在 O(log n) 时间内找到最小值

核心逻辑

1. 检查数组是否已排序

• 如果 nums[left] < nums[right],说明没有旋转,直接返回 nums[left]。

2. 二分查找

• 计算 mid = left + (right - left) / 2

对 nums[mid] 和 nums[right] 进行比较

若 nums[mid] > nums[right]

• mid 处于左半部分,最小值一定在右侧

移动 left = mid + 1

若 nums[mid] ≤ nums[right]

• mid 可能是最小值,或最小值在 mid 左侧

移动 right = mid(保留 mid)

循环直到 left == right,返回 nums[left]

✅ 代码实现

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        
        // 如果数组是有序的(未旋转)
        if (nums[left] < nums[right]) return nums[left];

        while (left < right) {  // 终止条件:left == right
            int mid = left + (right - left) / 2;

            if (nums[mid] > nums[right]) {  
                // mid 在左侧,最小值一定在右半部分
                left = mid + 1;
            } else {
                // mid 在右侧,最小值可能在 mid 及其左侧
                right = mid;
            }
        }
        return nums[left];  // 结束时 left == right,返回最小值
    }
};

📝 运行步骤

我们用 nums = [4, 5, 6, 7, 1, 2, 3] 作为示例,跟踪每一步的 left、right、mid 变化

迭代

left

right

mid

nums[mid]

nums[right]

操作

初始化

0

6

3

7

3

nums[left] > nums[right],进入二分查找

1

0

6

3

7

3

nums[mid] > nums[right] → left = mid + 1 = 4

2

4

6

5

2

3

nums[mid] ≤ nums[right] → right = mid = 5

3

4

5

4

1

2

nums[mid] ≤ nums[right] → right = mid = 4

结束

left == right == 4

-

-

-

-

返回 nums[4] = 1

最终答案:1

📊 复杂度分析

时间复杂度

空间复杂度

O(log n)

O(1)

时间复杂度:每次二分查找缩小一半范围,O(log n)

空间复杂度:只使用了 left 和 right 变量,O(1)

🔍 总结

使用二分查找,而不是遍历整个数组 O(n)。

核心判断条件

1. nums[mid] > nums[right],最小值在右侧

2. nums[mid] ≤ nums[right],最小值在左侧或 mid

终止条件:left == right,返回 nums[left] 即最小值

这样,我们就能高效地找到旋转排序数组中的最小值 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值