LeetCode 153. Find Minimum in Rotated Sorted Array 题解题目描述已知一个长度为n的数组预先按照升序排列经由1到n次旋转后得到输入数组。例如原数组nums [0,1,2,4,5,6,7]在变化后可能得到若旋转4次则可以得到[4,5,6,7,0,1,2]若旋转7次则可以得到[0,1,2,4,5,6,7]注意数组[a[0], a[1], a[2], ..., a[n-1]]旋转一次的结果为数组[a[n-1], a[0], a[1], a[2], ..., a[n-2]]。给你一个元素值互不相同的数组nums它原来是一个升序排列的数组并按上述情形进行了多次旋转。请你找出并返回数组中的最小元素。示例 1输入nums [3,4,5,1,2] 输出1 解释原数组为 [1,2,3,4,5] 旋转 3 次得到输入数组。示例 2输入nums [4,5,6,7,0,1,2] 输出0 解释原数组为 [0,1,2,4,5,6,7] 旋转 4 次得到输入数组。示例 3输入nums [11,13,15,17] 输出11 解释原数组为 [11,13,15,17] 旋转 4 次得到输入数组。解题思路方法二分查找思路由于数组是旋转排序的所以数组可以分为两部分每部分都是升序的且前一部分的所有元素都大于后一部分的所有元素。我们可以使用二分查找来快速定位最小元素。具体步骤初始化左指针left为 0右指针right为数组长度减 1。当left right时计算中间位置mid。比较nums[mid]和nums[right]的大小如果nums[mid] nums[right]说明最小元素在左侧将right设为mid。如果nums[mid] nums[right]说明最小元素在右侧将left设为mid 1。当left right时返回nums[left]此时left指向最小元素。复杂度分析时间复杂度O(log n)其中 n 是数组的长度。每次查找都会将查找区间减半。空间复杂度O(1)只需要常数级的额外空间。代码实现方法二分查找class Solution: def findMin(self, nums: List[int]) - int: # 初始化左指针和右指针 left 0 right len(nums) - 1 # 当左指针小于右指针时继续查找 while left right: # 计算中间位置 mid left (right - left) // 2 # 比较中间元素和右指针元素的大小 if nums[mid] nums[right]: # 最小元素在左侧将右指针移到中间位置 right mid else: # 最小元素在右侧将左指针移到中间位置的右边 left mid 1 # 当左指针等于右指针时返回左指针指向的元素此时左指针指向最小元素 return nums[left]测试用例测试用例 1输入nums [3,4,5,1,2]输出1测试用例 2输入nums [4,5,6,7,0,1,2]输出0测试用例 3输入nums [11,13,15,17]输出11总结本题是二分查找的经典变体问题主要考察对二分查找算法的理解和应用。通过比较中间元素和右指针元素的大小我们可以确定最小元素的位置在左侧还是右侧从而缩小查找区间。二分查找的核心思想是使用两个指针分别指向查找区间的两端计算中间位置比较中间元素与目标值的大小根据比较结果缩小查找区间直到找到目标值或确定目标值不存在。这种方法的时间复杂度为 O(log n)适用于大规模旋转排序数组的最小元素查找。掌握二分查找的原理对于理解搜索算法和算法设计思想非常重要。