每日一道演算法:搜尋插入位置

zhangdeTalk發表於2020-02-10

題目:給定一個排序陣列和一個目標值,在陣列中找到目標值,並返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。

你可以假設陣列中無重複元素。

示例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_PHP:https://github.com/zhangdejian/LeetCode_PHP

題目來源

力扣(LeetCode):https://leetcode-cn.com/problems/search-in...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

阿德

相關文章