給定一個排序數組和一個目標值,在數組中找到目標值,並返回其索引。若是目標值不存在於數組中,返回它將會被按順序插入的位置。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 //返回插入的下標位置 }