# 搜索插入位置(35)
# 题目
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
# 示例
输入: [1,3,5,6]
, 5
输出: 2
输入: [1,3,5,6]
, 2
输出: 1
输入: [1,3,5,6]
, 7
输出: 4
输入: [1,3,5,6]
, 0
输出: 0
# 算法
# 遍历
export const searchInput = (nums, target) => {
for (let i = 0; i < nums.length; i++) {
if (nums[i] >= target) return i;
}
return nums.length;
};
1
2
3
4
5
6
2
3
4
5
6
# 二分查找
使用二分查找,只要是左端点移动时,将左端点移动的值记录在变量minStart
中,如果找到值target
则直接返回,否则从minStart
开始依次向后寻找插入的位置
export const searchInput = (nums, target) => {
let [index, isFind] = binarySearch(nums, target);
if (isFind) return index;
while (index < nums.length && nums[index] < target) {
index++;
}
return index;
};
const binarySearch = (nums, target) => {
let start = 0,
end = nums.length - 1;
let minStart = 0;
while (start <= end) {
const mid = ~~((start + end) / 2);
if (nums[mid] < target) (start = mid + 1) && (minStart = mid);
else if (nums[mid] > target) end = mid - 1;
else return [mid, true];
}
return [minStart, false];
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 二分查找
题目分两种情况:
- 如果
nums
中有target
则返回下标 - 如果
nums
中找不到target
,则返回一个插入位置,即第一个比target
大的值的位置
所以题目等于——“返回一个大于等于target
的位置”
所以我们将nums[mid]>=target
的情况下(即移动右端点到中点时),将移动后的右端点的位置保存在变量index
中,(也等于将无限趋近target
且大于target
的值保存在index
中),待跳出循环(即start>end时)返回这个变量index
作为结果
index
默认为nums.length
可以免去边界判断,即当target
大于nums
中所有值时返回最后一个位置
export const searchInput = (nums, target) => {
let start = 0,
end = nums.length - 1;
let index = nums.length;
while (start <= end) {
const mid = ~~((start + end) / 2);
if (nums[mid] >= target) {
index = mid;
end = mid - 1;
} else {
start = mid + 1;
}
}
return index;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15