返回

寻找旋转排序数组中的插入位置:LeetCode 探索之路

前端

旋转排序数组的奥秘

想象一下一组数字,像魔方一样被旋转了一定角度。这就是旋转排序数组的本质。旋转后的数组可能看起来像:

[5, 6, 7, 8, 9, 1, 2, 3, 4]

虽然数组已经旋转,但数字仍然保持按升序排列。我们的任务是找到一个插入位置,使得插入的新元素后数组仍然保持升序。

二分查找的威力

二分查找是一种高效的搜索算法,适用于已排序的数组。它通过反复将搜索范围缩小一半,快速找到目标元素。对于旋转排序数组,我们采用以下改进的二分查找算法:

  1. 确定旋转点:

    • 将数组分为两个子数组:[left, mid][mid + 1, right].
    • 如果 nums[mid] > nums[right], 则旋转点位于 [left, mid] 中。
    • 如果 nums[mid] < nums[right], 则旋转点位于 [mid + 1, right] 中。
  2. 缩小搜索范围:

    • 根据旋转点,确定应该在哪个子数组中搜索。
    • 更新 leftright 指针以缩小搜索范围。
  3. 重复以上步骤:

    • 重复步骤 1 和 2,直到找到插入位置或排除所有可能性。

分步指南

以下是使用二分查找在旋转排序数组中查找插入位置的分步指南:

  1. 确定旋转点。
  2. 在正确的子数组中进行二分查找。
  3. 如果 nums[mid] == target, 返回 mid.
  4. 如果 nums[mid] < target, 更新 left 指针。
  5. 如果 nums[mid] > target, 更新 right 指针。
  6. 重复步骤 2-5,直到找到插入位置。
  7. 如果 left > right, 则插入位置为 right + 1.

示例代码

def search_insert_position(nums, target):
    left, right = 0, len(nums) - 1

    while left <= right:
        mid = (left + right) // 2

        if nums[mid] == target:
            return mid

        # 确定旋转点并缩小搜索范围
        if nums[mid] > nums[right]:
            if nums[mid] > target >= nums[left]:
                right = mid - 1
            else:
                left = mid + 1
        else:
            if nums[mid] < target <= nums[right]:
                left = mid + 1
            else:
                right = mid - 1

    # 旋转点位于数组末尾
    return right + 1

总结

使用改进后的二分查找算法,我们可以高效地在旋转排序数组中找到插入位置。这种算法不仅适用于 LeetCode 挑战,还适用于其他需要在旋转数组中进行搜索的实际场景。通过探索这种算法,我们加强了我们的算法技能并加深了我们对排序数组运作方式的理解。