Description

給定一個升序排列的整數陣列 nums 和一個目標值 target,在陣列中搜尋 target。如果存在回傳其索引,否則回傳 -1

Example:

Input: nums = [-1,0,3,5,9,12], target = 9 Output: 4

Intuition#

已排序陣列中,每次比較中間元素就能排除一半的搜尋空間。

  • 經典的二分搜尋:比較 midtarget
  • 相等則找到;target 較大則搜尋右半部;target 較小則搜尋左半部

Approaches#

1: Linear Scan#

  • 概念: 逐一掃描陣列找目標值
  • 時間複雜度: O(n)
  • 空間複雜度: O(1)
Linear Scan 程式碼
class Solution {
    fun search(nums: IntArray, target: Int): Int {
        for (i in nums.indices) {
            if (nums[i] == target) return i
        }
        return -1
    }
}
  • 概念: 維護 left 和 right 指標,每次取中間值比較,縮小搜尋範圍
  • 時間複雜度: O(log n)
  • 空間複雜度: O(1)
class Solution {
    fun search(nums: IntArray, target: Int): Int {
        var left = 0
        var right = nums.size - 1
        while (left <= right) {
            val mid = left + (right - left) / 2
            when {
                nums[mid] == target -> return mid
                nums[mid] < target -> left = mid + 1
                else -> right = mid - 1
            }
        }
        return -1
    }
}

使用 left + (right - left) / 2 而非 (left + right) / 2 來避免整數溢位。

🔑 Takeaways#

  • Pattern: 標準二分搜尋模板
  • 關鍵技巧: 注意迴圈條件 left <= right(閉區間)與 left < right(半開區間)的差異,兩種寫法對應不同的邊界更新方式