題目:給定一個排序陣列和一個目標值,在陣列中找到目標值,並返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。
你可以假設陣列中無重複元素。
示例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
相關標籤
* 陣列
* 二分查詢
解法一:暴力法
思路分析:
迴圈遍歷陣列,比較指標對應陣列位置的值與目標值的對比,因為是已經排序好的陣列,所以當出現大於等於時的指標就是結果,否則就是最大的值,陣列再加一位。
PHP程式碼實現:
/**
* @param Integer[] $nums
* @param Integer $target
* @return Integer
*/
function searchInsert($nums, $target) {
for($i=0;$i<count($nums);$i++){
if($nums[$i] >= $target){
return $i;
}
}
return count($nums);
}
使用:
$nums = [1,3,5,6];
$target = 7;
var_dump(searchInsert($nums, $target));
複雜度分析:
時間複雜度: O(n)
最好的情況是O(1),最壞的情況是O(n)
空間複雜度: O(1)
沒有額外空間被使用
當陣列長度大一點時,很容易超出時間限制和溢位記憶體,明顯是一個很粗暴的解決方法
解法二:二分查詢法
思路分析:
先設定左側下標 left 和右側下標 right,再計算中間下標 mid,每次根據 nums[mid] 和 target 之間的大小進行判斷,相等則直接返回下標,nums[mid] < target 則 left 右移,nums[mid] > target 則 right 左移,查詢結束如果沒有相等值則返回 left,該值為插入位置。
PHP程式碼實現:
/**
* @param Integer[] $nums
* @param Integer $target
* @return Integer
*/
function searchInsert($nums, $target) {
$left = 0;
$right = count($nums)-1;
while($left<=$right){
$mid = intval(($left+$right)/2);
if($nums[$mid] == $target){
return $mid;
}elseif($nums[$mid] > $target){
$right = $mid -1;
}else{
$left = $mid+1;
}
}
return $left;
}
使用:
$nums = [1,3,5,6,88,90];
$target = 100;
var_dump(searchInsert($nums, $target));
複雜度分析:
時間複雜度: O(logn)
最好的情況是O(1),最壞的情況是O(logn)
空間複雜度: O(1)
沒有額外空間被使用
二分查詢法是最優解法
二分查詢的模板
在遇到二分查詢相關的演算法題,都可以套用以下模板。
/**
* 二分查詢的模板
* @param Integer[] $nums
* @param Integer $target
* @return Integer
*/
function blade($nums, $target) {
$left = 0;
$right = count($nums)-1;
while($left<=$right){//注意條件界限
$mid = intval(($left+$right)/2);//注意取整
if($nums[$mid] == $target){
//相關邏輯處理;
}elseif($nums[$mid] > $target){//注意right向左偏移
$right = $mid -1;
}else{//注意left向右偏移
$left = $mid+1;
}
}
//相關值返回
return 0;
}
解題關鍵
在做演算法題時,整理思路很重要,有時確實沒特別完整的思路時,可以先動手寫寫,在寫的過程中有時思路就會不斷崩出(可能是程式碼感覺可以激發想法吧,哈哈)。在程式碼寫出來之後,一定要總結規律和精簡程式碼,因為優秀的程式碼都是很精簡的。
github
以後每次題解都會上傳到這個專案
題目來源
力扣(LeetCode):https://leetcode-cn.com/problems/search-in...
本作品採用《CC 協議》,轉載必須註明作者和本文連結