LeetCode35-搜索插入位置

题目链接

英文链接:https://leetcode.com/problems/search-insert-position/

中文链接:https://leetcode-cn.com/problems/search-insert-position/

题目详述

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:

1
2
输入: [1,3,5,6], 5
输出: 2

示例 2:

1
2
输入: [1,3,5,6], 2
输出: 1

示例 3:

1
2
输入: [1,3,5,6], 7
输出: 4

示例 4:

1
2
输入: [1,3,5,6], 0
输出: 0

题目详解

直观方法:

  • 由于数组是有序的,如果目标值存在于数组中,返回索引即可。
  • 如果目标值不存在于数组中,那么数组中第一个大于目标值的元素的索引就是插入的位置。如果数组中所有元素均小于目标值,那么插入的位置就是最大元素的下一个位置,也就是位于数组的长度处。
  • 所以可以遍历数组,找到第一个大于或等于目标值的元素,返回其索引;若找不到,返回数组的长度。
1
2
3
4
5
6
7
8
9
10
11
public class LeetCode_00035 {

public int searchInsert(int[] nums, int target) {
for (int i = 0; i < nums.length; ++i) {
if (nums[i] >= target) {
return i;
}
}
return nums.length;
}
}

二分法:

  • ”数组 + 有序“可以联想到二分查找。
  • 显然,插入点的范围在 [0, nums.length] 之间,可令 lo = 0, hi = nums.length。
  • 二分查找过程中,若 target > nums[mid],插入点所在区间不包含 mid;若 target < nums[mid],插入点所在区间是包含 mid 的。若二者相等,直接返回 mid 即可。
  • 二分查找的终止条件是插入点所在区间收缩到一个点,即 lo == hi。当 lo == hi 时,返回其一即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LeetCode_00035 {

public int searchInsert(int[] nums, int target) {
int lo = 0;
int hi = nums.length;
// 插入点的范围在 [0, nums.length] 中。lo == hi 时,lo 就是插入点。
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (target > nums[mid]) {
lo = mid + 1; // 插入点所在区间不包含 mid
} else if (target < nums[mid]) {
hi = mid; // 插入点所在区间包含 mid
} else {
return mid;
}
}
return lo;
}
}