题目:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。
我的方案:
思路
我把这个题分成两部分,第一部分是查询是否有这个数字,因为数组无重复,所以使用哈希表。第二部分是,查找这个数字应该插入的位置。
算法
先建立一个map集合,将数组的值作为键,数组的索引作为值。当查找不到值时,在数组中从头遍历比target值大的项,找到就返回,找不到说明target是最大的,直接返回数组总长。查找到值直接返回。
代码
- java:
class Solution {
public int searchInsert(int[] nums, int target) {
//边界判断
if(nums==null)
return 0;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
//将数组的值与索引作为键值对存储到Map中
for(int i = 0;i<nums.length;i++){
map.put(nums[i],i);
}
//在Map中没有找到目标值,用循环在有序数组中找到第一个大于目标值的索引
if(map.get(target)==null){
int i;
for(i = 0;i<nums.length;i++){
if(nums[i]>target){
return i;
}
}
return nums.length;
//找到目标值即输出
}else{
return map.get(target);
}
}
}
官方精选方案
思想
算法
首先判断边界条件,然后使用左中位数的二分查找模板,最后得到的值一定是题解。
代码
public class Solution {
public int searchInsert(int[] nums, int target) {
int len = nums.length;
if (len == 0) {
return 0;
}
int left = 0;
int right = len;
//不用在每次循环开始单独考虑中位数是否是目标元素,节约了时间,我们只要在退出循环的时候,即左右区间压缩成一个数(索引)的时候,去判断这个索引表示的数是否是目标元素,而不必在二分的逻辑中单独做判断。
while (left < right) {
int mid = (left + right) >>> 1;
if (nums[mid] < target) {
//舍弃nums[mid]
left = mid + 1;
} else {
//不舍弃nums[mid]
right = mid;
}
}
return left;
}
}