本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/se… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
在一个有序数组中查找目标值,首先想到二分查找,时间复杂度O(logn) ,比直接遍历数组效率高。能力有限,只会写递归方式的二分查找。首先是边界判断,如果在头尾,则直接处理;其次就是用二分法比较中间的元素与target的大小,当中间元素等于target时(返回mid下标),或者start/end指针相邻时结束查找(nums[start==mid] != target,end所在的值必然等于或大于target,返回end下标)。
代码展示
public static int searchInsert(int[] nums, int target) {
int length = nums.length;
if (length == 0)
return 0;
// 边界判断
if (nums[0] >= target)
return 0;
if (nums[length - 1] <= target)
return length;
// 二分查找
return binarySearch(0, length - 1, nums, target);
}
public static int binarySearch(int start, int end, int[] nums, int target) {
// 获取中间下标
int mid = (end + start) / 2;
// 比较中间元素与target是否相等
if (nums[mid] == target)
return mid;
// 判断查找的下标是否相邻,此时小下标nums[start==mid] != target,因此大下标必然满足nums[end] >= target
if (end - start == 1) {
return end;
} else {
return nums[mid] > target ? binarySearch(0, mid, nums, target) : binarySearch(mid, end, nums, target);
}
}
总结
大神的写法还是更简洁明了,佩服!!!
官方题解
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int left = 0, right = n - 1, ans = n;
while (left <= right) {
int mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
}