搜尋插入位置( Search-Insert-Position )
題幹:
給定一個排序陣列和一個目標值,在陣列中找到目標值,並返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。
你可以假設陣列中無重複元素。
示例 1:
輸入: [1,3,5,6], 5
輸入: 輸出: 2
示例 3:
輸入: 輸入: [1,3,5,6], 7
輸入: 輸出: 4
示例 4:
輸入: 輸入: [1,3,5,6], 0
輸入: 輸出: 0
來源:力扣
這題主要應用 二分查詢 的思路來解題,題目是比較簡單的,但是 二分查詢 這個思路還是蠻重要的。
解題思路
一般使用 二分查詢 都需要先對原陣列進行排序,題中給到的陣列是已經排序的,因此這一步可以省去。
二分查詢 思路比較簡單,首先初始化三個指標: left 指向 nums 最左邊的元素,right 指向 nums 右邊的元素,根據 left 和 right 計算 mid 指標。我們先拿目標值 target 與 nums[mid] 進行比較。
如果 target > nums[mid],說明要查詢的值有可能在 nums[mid+1, right] 之間,這時候將 left 賦值為 mid + 1,right 不變,重新計算一下 mid,重新比較。
如果 target < nums[mid],說明要查詢的值有可能在 nums[left, mid-1] 之間,這時候將 right 賦值為 mid - 1,left 不變,重新計算一下mid,重新比較。
如果 target == nums[mid],那麼恭喜找到啦,根據題意,找到的索引值就是 target 插入的目標位置,即返回 mid 即可。
如果 二分查詢 結束仍是沒有找到 target 的值,最後返回 left 就可以了,至於為什麼 left 的值是 target 插入的位置,可以看流程圖的分析。
mid 的計算方式: mid = left + ( rigth - left ) / 2,至於為什麼不用 ( left + right ) / 2 來計算 mid 是因為 right + left 有可能溢位。
注: ( right - left) / 2 取整,因為陣列的索引值是整數。
流程圖如下:
程式碼實現
// 函式的實現並不是最簡潔的,但是整個二分法思路是很清晰的。
func searchInsert(nums []int, target int) int {
if len(nums) <= 0 {
return 0
}
var left, right = 0, len(nums) - 1
for left <= right {
// 根據 left 和 right 計算 mid 的值
mid := left + (right - left) / 2 // ( left + right ) / 2
// 目標值大於中間值,left = mid + 1
if nums[mid] < target {
left = mid + 1
// 目標值小於中間值 right = mid - 1
} else if nums[mid] > target {
right = mid - 1
} else {
// 目標值等於中間值返回 mid,即為目標值需要插入的位置
return mid
}
}
// 找不到目標值,這時候返回left就是目標值需要插入的位置
return left
}
總結
每天進步一點點,加油!
演算法教程專案,每天更新一題,點個 star 支援一下呀:
https://github.com/wx-satellite/learning-a…
本作品採用《CC 協議》,轉載必須註明作者和本文連結