原题链接🔗:搜索插入位置
难度:简单⭐️
题目
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
- 1 <= nums.length <= 104
- -104 <= nums[i] <= 104
- nums 为 无重复元素 的 升序 排列数组
- -104 <= target <= 104
二分查找法
二分查找法是一种在有序数组中查找特定元素的算法。它的基本思想是将目标值与数组中间的元素进行比较,根据比较结果缩小搜索范围,然后重复这个过程,直到找到目标值或搜索范围为空。
-
算法步骤
- 初始化:设置两个指针,
left
指向数组的起始位置,right
指向数组的结束位置。 - 循环条件:当
left
小于等于right
时,继续循环。 - 计算中间位置:计算中间索引
mid
,通常使用(left + right) // 2
(使用整数除法以避免浮点数结果)。 - 比较:
- 如果
nums[mid]
等于目标值,返回mid
,表示找到了目标值的位置。 - 如果
nums[mid]
大于目标值,移动right
到mid - 1
,排除数组中间到right
的部分。 - 如果
nums[mid]
小于目标值,移动left
到mid + 1
,排除数组left
到中间的部分。
- 如果
- 结束循环:当
left
大于right
时,循环结束,表示没有找到目标值,此时left
的位置就是目标值应该插入的位置,以保持数组的有序性。
- 初始化:设置两个指针,
-
复杂度分析
- 时间复杂度:O(log n),其中 n 是数组的长度。这是因为每次比较后,搜索范围减半。
- 空间复杂度:O(1),因为二分查找不需要额外的存储空间。
-
代码示例(Python)
def binary_search(nums, target):
left, right = 0, 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 left # 如果没有找到,返回left作为插入位置
-
注意事项
- 二分查找要求数组是有序的,无论是升序还是降序。
- 如果数组中有重复的元素,二分查找仍然有效,但可能不会返回第一个或最后一个匹配项的索引。
- 在实际应用中,如果数组非常大,需要考虑整数溢出的问题,可以通过
left + (right - left) // 2
来避免这个问题。
-
二分查找是一种非常高效的搜索算法,适用于大规模数据集的查找任务。
题解
- 解题思路:
LeetCode 上的 “搜索插入位置”(Search Insert Position)是一道非常经典的二分查找问题。题目要求你给定一个已排序的整数数组 nums 和一个目标值 target,找出 target 插入到数组中后,数组仍然保持有序的位置。
解题思路:
- 二分查找:由于数组是有序的,可以使用二分查找算法来确定目标值的位置。
- 初始化:定义两个指针 left 和 right,分别指向数组的开始和结束。
- 循环条件:当 left 小于等于 right 时,继续循环。
- 计算中间位置:计算中间位置 mid,通常使用 (left + right) / 2。
- 比较:
- 如果 nums[mid] 等于 target,则返回 mid。
- 如果 nums[mid] 小于 target,则将 left 更新为 mid + 1。
- 如果 nums[mid] 大于 target,则将 right 更新为 mid - 1。
- 返回结果:循环结束后,left 将指向 target 应该插入的位置。
- c++ demo:
#include <iostream>
#include <vector>
// 函数声明
int searchInsert(std::vector<int>& nums, int target);
int main() {
// 测试用例
std::vector<int> nums = { 1, 3, 5, 6 };
int target = 5;
// 调用函数并输出结果
int insertPosition = searchInsert(nums, target);
std::cout << "Insert position for target " << target << " is: " << insertPosition << std::endl;
return 0;
}
// 搜索插入位置的函数实现
int searchInsert(std::vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止溢出
if (nums[mid] == target) {
return mid;
}
else if (nums[mid] < target) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return left; // 循环结束后,left指向插入位置
}
- 输出结果:
Insert position for target 5 is: 2
- 代码仓库地址:searchInsert