返回
剖析算法精髓:LeetCode 153 寻找旋转排序数组中的最小值
前端
2024-02-17 17:18:27
在浩瀚的算法海洋中,LeetCode 153 寻找旋转排序数组中的最小值犹如一颗璀璨的明珠,吸引着无数算法爱好者的目光。这道题不仅考察了算法的基本功,还对二分查找算法的应用提出了更高的要求。接下来,我们将深入剖析这道题目的解题思路,带你领略算法的魅力。
题目
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次旋转后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:[4,5,6,7,0,1,2] 或 [0,1,2,4,5,6,7]。请你找出旋转后的数组中的最小值。
算法思路
LeetCode 153 寻找旋转排序数组中的最小值的关键在于二分查找算法的巧妙应用。二分查找是一种高效的搜索算法,它通过不断地将搜索范围减半来快速找到目标元素。在旋转排序数组中,我们无法直接使用二分查找算法,因为数组的顺序已经被破坏了。
为了解决这个问题,我们需要先找到旋转点,即数组中顺序发生改变的位置。旋转点可以将数组分为两个有序的部分。找到旋转点后,我们就可以分别在两个有序部分中使用二分查找算法来找到最小值。
具体来说,我们可以通过以下步骤来找到旋转点和最小值:
- 初始化两个指针 left 和 right,分别指向数组的第一个元素和最后一个元素。
- 计算中点 mid = (left + right) / 2。
- 如果 nums[mid] > nums[right],说明旋转点在 [left, mid] 之间,将 right 更新为 mid。
- 如果 nums[mid] < nums[right],说明旋转点在 [mid+1, right] 之间,将 left 更新为 mid+1。
- 重复步骤 2-4,直到 left 等于 right。此时,left 和 right 指向的元素就是旋转点。
- 将数组分为 [left, mid] 和 [mid+1, right] 两个有序部分。
- 在 [left, mid] 和 [mid+1, right] 两个有序部分中分别使用二分查找算法找到最小值。
代码实现
def find_min(nums):
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
return nums[left]
if __name__ == "__main__":
nums = [4, 5, 6, 7, 0, 1, 2]
result = find_min(nums)
print(result) # 0
总结
LeetCode 153 寻找旋转排序数组中的最小值是一道经典的算法题,它不仅考察了算法的基本功,还对二分查找算法的应用提出了更高的要求。通过剖析这道题目的解题思路,我们不仅掌握了寻找旋转点和最小值的方法,也对二分查找算法有了更深入的理解。希望这篇文章能帮助你提升算法能力,在算法的道路上更进一步。