业精于勤,荒于嬉!
无他,唯手熟尔!
题目描述
35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
题解
法一:二分查找
思路与算法
假设题意是叫你在排序数组中寻找是否存在一个目标值,那么训练有素的读者肯定立马就能想到利用二分法在 O(logn) 的时间内找到是否存在目标值。但这题还多了个额外的条件,即如果不存在数组中的时候需要返回按顺序插入的位置,那我们还能用二分法么?答案是可以的,我们只需要稍作修改即可。
考虑这个插入的位置pos,它成立的条件为:
nums[pos−1]<target≤nums[pos]
其中 nums 代表排序数组。由于如果存在这个目标值,我们返回的索引也是pos,因此我们可以将两个条件合并得出最后的目标:「在一个有序数组中找第一个大于等于 target 的下标」。
问题转化到这里,直接套用二分法即可,即不断用二分法逼近查找第一个大于等于target 的下标 。
C++
class Solution {
public:
int searchInsert(vector<int>& nums, int target)
{
int n = nums.size();
int left = 0, right = n - 1;
while (left <= right)
{
//先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (3 + 2))&7.
//移位时先换算成二进制后再移位
int mid = ((right - left) >> 1) + left;
if (target <= nums[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
return left;
}
};
法二:暴力搜索法
C++
class Solution
{
public:
int searchInsert(vector<int>& nums,int target)
{
for(int i=0;i<nums.size();i++)
{
//若nums[i]>target,则说明target不在数组中,并且i就是target要插入的索引
//若nums[i]=target,则说明target再数组中,i就是要返回的索引
if(nums[i]>=target) return i;
}
return nums.size();
}
}
C
int searchInsert(int* nums,int numsSize,int target)
{
int i;
for(i=0;i<numsSize;i++)
{
if(nums[i]>=target)
{
return i;
}
}
return numsSize;
}
法三: 运用c++STL标准库函数
lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。
//函数所在头文件
#include <algorithm> // std::lower_bound
class Solution
{
public searchInsert(vector<int> &nums,int numsSize,int target)
{
return lower_bound(nums.begin(),nums.end(),target)-nums.begin();
}
}
附
STL标准模板库提供三种类型的组件:
- 容器,迭代器和算法,他们都支持泛型程序设计标准;
容器主要分为两大类:
- 顺序容器和关联容器。顺序容器有: (vector, list, deque和string等)是一系列元素的有序集合。
- 关联容器: (set, multiset,map, multimap)包含查找元素的键值;
迭代器的作用是遍历容器;
vector迭代器定义:
vector<int>::iterator it
iter1-iter2 //两个迭代器相减是它们之间的距离。
//参与运算的两个迭代器必须指向同一个容器中的元素或为尾后迭代器
//其类型为difference_type的带符号整型数。