📜  门|门 IT 2006 |问题 26(1)

📅  最后修改于: 2023-12-03 15:12:46.575000             🧑  作者: Mango

门|门 IT 2006 |问题 26

该问题来自于“门|门 IT 2006”,是一道典型的编程问题。

问题描述

有一个长度为 $n$ 的整数数组 $nums$,旋转后得到一个有序数组。假设数组中可能存在重复元素。请你找出数组中的最小元素。

示例 1:

输入:nums = [1,3,5] 输出:1

示例 2:

输入:nums = [2,2,2,0,1] 输出:0

解题思路

这是一道经典的二分查找问题,虽然数组中可能存在重复元素,但跟没有重复元素的二分查找问题非常类似,只是在相等的情况下需要特殊处理。

具体来说,二分查找的过程中,首先需要确定指针 $left$ 和 $right$ ,然后计算出中间位置 $mid$。接着比较 $nums[mid]$ 与 $nums[right]$ 的大小关系,如果 $nums[mid] < nums[right]$,则说明最小值一定在左半边,将 $right$ 赋值为 $mid$;如果 $nums[mid] > nums[right]$,则说明最小值一定在右半边,将 $left$ 赋值为 $mid + 1$;否则,$nums[mid]$ 可能等于 $nums[right]$,也可能不等于 $nums[right]$。为了排除 $nums[right]$ 的影响,需要将 $right$ 减去 $1$,然后再进行比较。

每次比较之后,都需要将数组划分为新的左右两个区间,并重复上述过程,直到左右指针相遇。最后,指针 $left$ 所在的位置,就是最小值。

代码实现
def findMin(nums: List[int]) -> int:
    left, right = 0, len(nums) - 1
    while left < right:
        mid = (left + right) // 2
        if nums[mid] < nums[right]:
            right = mid
        elif nums[mid] > nums[right]:
            left = mid + 1
        else:  # nums[mid] == nums[right]
            right -= 1
    return nums[left]
总结

本题是一道非常经典的二分查找问题,需要注意处理相等的情况。掌握二分查找算法的核心思想和流程很重要,在实际工程项目中也有着广泛的应用。