给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。若是目标值不存在于数组中,返回它将会被按顺序插入的位置。golang
你能够假设数组中无重复元素。数组
示例 1:
输入: [1,3,5,6], 5
输出: 2code
示例 2:
输入: [1,3,5,6], 2
输出: 1blog
示例 3:
输入: [1,3,5,6], 7
输出: 4排序
示例 4:
输入: [1,3,5,6], 0
输出: 0索引
1.目标值所在的位置无非就是以下四种状况:get
2.由题目可知所给的数组为有序数组,且数组中无重复元素,则咱们能够考虑使用二分法进行查找for循环
二分查找涉及的不少的边界条件,逻辑比较简单,就是写很差。
例如究竟是 while(left < right) 仍是 while(left <= right),究竟是right = middle呢,仍是要right = middle - 1呢?有时候就会搞混乱了😑,但只要咱们搞清楚就很是好写啦~class
(ps:golang没有传统意义上的while循环语句,它遵循大道至简的原则,用一种语法表示其余多种语法,故golang中能够用for循环代替while循环)变量
对于[left,right]左闭右闭的状况 选择 while(left <= right) , right = middle -1
对于[left,right)左闭右开的状况,选择 while(left < right) , right = middle
即要在二分查找的过程当中,保持不变量,这也就是「循环不变量」
代码以下:
/*采起左闭右闭状况*/ func searchInsert(nums []int, target int) int { left := 0 right := len(nums) - 1 for left <= right { //[left,right] left==right有效 //middle := (left + right) / 2 middle := left + ((right - left) >> 1) //防止整数溢出至关于(left+right)/w 并利用移位提升速度 >>1 至关于除2 if nums[middle] > target { right = middle - 1 } else if nums[middle] < target left = middle + 1 } else { //此时target == num[middle] 返回索引 return middle } } return right + 1 //返回插入的下标位置 }