给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
输入: [1,3,5,6], 5
输出: 2
输入: [1,3,5,6], 2
输出: 1
输入: [1,3,5,6], 7
输出: 4
输入: [1,3,5,6], 0
输出: 0
二分法
二分法的思想,前提是已经排序,其实就是每次找到中间的索引的值和目标值判断,三种情况:
- 如果相等,则返回该索引
- 如果该值小于目标值,说明目标值肯定在该值的右边区域,那么我就把左边区域扔掉,我只要右边区域。
- 如果该值大于目标值,说明目标值肯定在该值的左边区域,那么我就把右边区域扔掉,我只要左边区域。
但是这道题,还有一个小问题,如果该值不存在,返回它将会被按顺序插入的位置。 所以,有两种情况:
- 如果
l==0 && r < 0
,类似于这种情况:[3, 5, 6] and target = 2
,则返回索引0 - 否则,返回
(l + r) / 2
+ 1,类似于这种情况:[3, 5, 6] and target = 4
let searchInsert = (nums, target) => {
if (nums === undefined || nums.length === 0)
return -1;
let l = 0, r = nums.length - 1;
while (l <= r) {
let m = (l + (r - l) / 2) | 0;
if (nums[m] === target)
return m;
else if (nums[m] < target) {
l = m + 1;
} else {
r = m - 1;
}
}
// 注意边界
if (r < 0 && l === 0)
return (((l + r) % 2) | 0) + 1;
else
return (((l + r) / 2) | 0) + 1;
}
console.log(searchInsert([1, 3, 5, 6], 5));
console.log(searchInsert([1, 3, 5, 6], 2));
console.log(searchInsert([1, 3, 5, 6], 7));
console.log(searchInsert([1, 3, 5, 6], 0));
func searchInsert(nums []int, target int) int {
if nums == nil || len(nums) == 0 {
return -1
}
l, r := 0, len(nums) - 1
for l <= r {
m := l + (r - l) / 2
if nums[m] == target {
return m
} else if nums[m] < target {
l = m + 1
} else {
r = m - 1
}
}
// 注意边界
if r < 0 && l == 0 {
return (l + r) % 2 + 1
} else {
return (l + r) / 2 + 1
}
}
class Solution {
public int searchInsert(int[] nums, int target) {
if (nums == null || nums.length == 0)
return -1;
int l = 0, r = nums.length - 1;
while (l <= r) {
int m = l + (r - l) / 2;
if (nums[m] == target)
return m;
else if (nums[m] < target)
l = m + 1;
else
r = m - 1;
}
// 注意边界
if (r < 0 && l == 0)
return (l + r) % 2 + 1;
else
return (l + r) / 2 + 1;
}
}