返回
LeetCode:在旋转的数组中找到目标值
前端
2024-01-07 04:56:16
旋转数组中的目标值查找:算法指南
旋转数组的定义
旋转数组是指将一个数组中的元素向左或向右移动一定数量的单位,使其形成一个新的数组。例如,将数组 [1, 2, 3, 4, 5] 向左移动两个单位,得到新的数组 [3, 4, 5, 1, 2]。
算法实现
在旋转数组中查找目标值时,二分查找算法变得更加复杂。以下是改进后的算法步骤:
- 找到数组的最小值: 通过二分查找算法找到数组中最小值的索引,该值将作为数组的起点。
- 将数组分为两部分: 以最小值索引为分界点,将数组分为左右两部分。
- 分别在两部分中进行二分查找: 分别在左右两部分中使用标准的二分查找算法查找目标值。
- 返回目标值的下标: 如果在任一部分中找到目标值,则返回其下标,否则返回 -1。
示例代码(Python):
def find_target_in_rotated_array(nums, target):
"""
在旋转数组中查找目标值
Args:
nums: 旋转数组
target: 目标值
Returns:
目标值的下标,如果没有找到,返回 -1
"""
# 找到数组的最小值
min_index = find_min_index(nums)
# 将数组分为两部分
left_part = nums[min_index:]
right_part = nums[:min_index]
# 在两部分中分别进行二分查找
left_index = binary_search(left_part, target)
right_index = binary_search(right_part, target)
# 返回目标值的下标
if left_index != -1:
return left_index + min_index
elif right_index != -1:
return right_index
else:
return -1
def find_min_index(nums):
"""
找到旋转数组的最小值
Args:
nums: 旋转数组
Returns:
最小值的下标
"""
left = 0
right = len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
return left
def binary_search(nums, target):
"""
在有序数组中进行二分查找
Args:
nums: 有序数组
target: 目标值
Returns:
目标值的下标,如果没有找到,返回 -1
"""
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
总结
通过将旋转数组分成两部分并分别应用二分查找算法,我们可以有效地在旋转数组中查找目标值。这种算法具有较好的时间复杂度,为 O(log n),其中 n 是数组的长度。
常见问题解答
-
为什么在旋转数组中不能直接使用二分查找算法?
因为旋转数组中不存在有序区间,无法直接应用二分查找算法。 -
算法中如何找到旋转数组的最小值?
通过二分查找算法,比较数组中相邻元素的值,将最小值移动到数组的起点。 -
如何将旋转数组分为两部分?
以最小值索引为分界点,数组的一部分位于其左侧,另一部分位于其右侧。 -
算法在两部分中分别进行二分查找的原因是什么?
因为在旋转数组中,目标值可能位于任何一部分。 -
如果旋转数组中存在重复元素,算法会发生什么变化?
算法仍然适用,但需要使用其他方法(如线性搜索)来处理重复元素。