数据结构与算法之 leetcode 二分查找变种题 旋转数组 / 搜索插入 攻略

数据结构与算法阿木 发布于 4 天前 2 次阅读


二分查找变种题攻略:旋转数组与搜索插入

二分查找是一种高效的查找算法,其基本思想是将有序数组分成两半,根据目标值与中间值的比较结果,决定在数组的哪一半继续查找。在实际应用中,我们可能会遇到一些特殊的数组,如旋转数组。旋转数组是一种经过某种方式旋转的有序数组,其查找过程与普通有序数组有所不同。还有一种变种题是搜索插入,它要求在有序数组中找到目标值应该插入的位置。本文将围绕这两个变种题,探讨二分查找的优化策略。

旋转数组

问题描述

给定一个按照非降序排列的整数数组 nums,假设数组已经旋转,比如 nums = [0,1,2,4,5,6,7] 经旋转后可能变为 [4,5,6,7,0,1,2]。请编写一个函数,找出这个旋转数组中的目标值 target 的索引。

解题思路

1. 初始化两个指针 left 和 right,分别指向数组的开始和结束。

2. 当 left 小于等于 right 时,计算中间索引 mid。

3. 比较中间值 nums[mid] 与目标值 target:

- 如果 nums[mid] 等于 target,返回 mid。

- 如果 nums[mid] 大于等于 nums[left],说明左半部分有序:

- 如果 nums[left] 小于等于 target 且 nums[mid] 大于 target,说明目标值在左半部分,将 right 更新为 mid - 1。

- 否则,将 left 更新为 mid + 1。

- 如果 nums[mid] 小于等于 nums[right],说明右半部分有序:

- 如果 nums[mid] 小于 target 且 nums[right] 大于 target,说明目标值在右半部分,将 left 更新为 mid + 1。

- 否则,将 right 更新为 mid - 1。

4. 如果循环结束后未找到目标值,返回 -1。

代码实现

python

def search(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[left]:


if nums[left] <= target < nums[mid]:


right = mid - 1


else:


left = mid + 1


else:


if nums[mid] < target <= nums[right]:


left = mid + 1


else:


right = mid - 1


return -1


搜索插入

问题描述

给定一个按非降序排列的整数数组 nums 和一个整数 target,请编写一个函数,在数组中找到 target 应该被插入的位置。

解题思路

1. 初始化两个指针 left 和 right,分别指向数组的开始和结束。

2. 当 left 小于等于 right 时,计算中间索引 mid。

3. 比较中间值 nums[mid] 与目标值 target:

- 如果 nums[mid] 等于 target,返回 mid。

- 如果 nums[mid] 大于 target,将 right 更新为 mid - 1。

- 如果 nums[mid] 小于 target,将 left 更新为 mid + 1。

4. 循环结束后,如果 left 等于 nums 的长度,说明 target 应该插入到数组的末尾;否则,返回 left。

代码实现

python

def searchInsert(nums, target):


left, right = 0, len(nums)


while left < right:


mid = (left + right) // 2


if nums[mid] == target:


return mid


elif nums[mid] > target:


right = mid


else:


left = mid + 1


return left


总结

本文介绍了二分查找的两个变种题:旋转数组和搜索插入。通过分析问题,我们找到了相应的解题思路,并给出了代码实现。这两个变种题在面试和实际应用中都非常常见,掌握它们的解题方法对于提高编程能力具有重要意义。在实际编程过程中,我们需要根据具体问题选择合适的算法,以达到最优的性能。