给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。 示例 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“排序数组”,其实就是在疯狂暗示用二分查找法
1、取中位数:int mid=(left+right)/2:当left和right较大的时候,可能会超过int类型所表示的最大值,即整形溢出,为了避免这个问题最好的写法为:int mid=(left+right)>>>1;(无符号右移) 2、循环时进行的条件可以写成while(left<right)时,在退出循环的时候,left一定和right相等,此时返回left或者right都可以,当然最后一个left或者right的数需要在循环体之外判断
public static int searchInsert(int[] nums,int target){ int length=nums.length; if(length==0) return -1; if(nums[0]>target) return 0; if(nums[length-1]<target) return length; int left=0; int right=length-1; while(left<right){ int mid=(left+right)>>>1; if(nums[mid]<target){ //如果判断nums[mid]<target,则把left赋值为mid+1,即mid的右一位 left=mid+1; }else{ right=mid; } return left;//或者return right;因为此时的left一定和right相等,所以返回left和right都是一样的 } }else中包含两种情况:nums[mid]=target或者nums[mid]>target, 而如果相等的话,则直接把mid赋值给right,而此时又会出现以下情况: 一、target在数组的左侧或者就是数组的中位数,right已经是要找的那个数了,此时right=mid,进行下一次while循环,但left<right(上一次while循环的mid),此时,while会继续循环,使left一直mid+1,就这样一直“夹逼”下去,直到left=right; 二、target在数组的右侧,此时已经经过数轮的while循环,经过left数轮的“夹逼”,判断的范围越来越小,越来越逼近target,假设此时的nums[mid]=target,那么使right=mid,此时又回到的“一”所说的情况,虽然nums[mid]已经是target,但是left<right,此时仍需遍历让left不断的等于mid+1 三、最后一种就是最理想的一种,就是通过不断的“夹逼”,已经“夹逼”到left和right相邻的情况,此时又有两种可能: 1)若nums[left]=target,经过else使right=mid(即left),退出for循环; 2)若nums[right]=target,则会使left+1,此时left=right,退出for循环
