--- tags: 演算法, LeetCode disqus: HackMD --- # 二分搜尋法(Binary search) ## 介紹 `Binary search`又稱作二分搜尋法,是查找項目的演算法,那看到二分就知道是將要查找的項目分成兩半做搜尋,直到找到我們要找的目標。  (圖片來自於[Binary Search](https://brilliant.org/wiki/binary-search/)) 不知道大家有沒有玩過猜數字遊戲,假設出題者出了一個數字`56`,而猜題者要從`1~100`之間猜數字,直到猜中為止,那當猜題者先猜`46`,出題者會告訴你比我的數字小,這時範圍就從`1~100`變成`47~100`,依此類推直到猜到數字。 我們可以使用二分搜尋法套用在猜數字遊戲上面,步驟為以下: 1. 找到最大值與最小值 2. 找到當前最大值與最小值的平均數(無條件捨去取整數) 3. 假設平均數等於目標數,代表成功了 4. 假設平均數小於目標值,則將最小值設為平均數加一 5. 假設平均數大於目標值,則將最大值設為平均數減一 6. 若無找到目標數則返回第二步驟  ## 複雜度 ### 時間複雜度 最好 $O(1)$ 最壞 $O(logn)$ ### 空間複雜度 迭代 $O(1)$ 遞迴 $O(logn)$ ## 實戰 可以透過`leetcode 704`[binary-search](https://leetcode.com/problems/binary-search/)來練習  ### 題目說明: 給定一個排序好的陣列,找到目標數的索引位置,找不到則回傳-1。 時間複雜度必須為O(log n) ### 解題: 以下圖解為第一個例題  1. 設定最左邊(left)為0,最右邊(right)為陣列數減一 2. 找到中心位置(mid)為當前最左邊跟最右邊的平均值(向下取整數) 3. 如果中心數字(nums[mid])跟目標數(target)相同則回傳 4. 如果中心數字大於目標數則right等於中心位置減一 5. 如果中心數字小於目標數則left等於中心位置加一 6. 未找到且left小於等於right,則回到步驟2 7. 如果right大於left,則停止:目標不存在於數組中。返回-1 #### 迭代寫法 ```javascript= /** * @param {number[]} nums * @param {number} target * @return {number} */ var search = function(nums, target) { let left = 0; let right = nums.length - 1; let mid = Math.floor((left + right) / 2); while (left <= right) { if (nums[mid] === target) { return mid; } else if (nums[mid] > target) { right = mid - 1; } else { left = mid + 1; } mid = Math.floor((left + right) / 2); } return -1; }; ``` #### 遞迴寫法 ```javascript= /** * @param {number[]} nums * @param {number} target * @return {number} */ var search = function(nums, target) { function search(low, high) { if (low > high) { return -1; } let mid = Math.floor((low + high) / 2); if (nums[mid] === target) { return mid; } else if (nums[mid] < target) { return search(mid + 1, high); } else { return search(low, mid - 1); } } return search(0, nums.length - 1); }; ``` 以下這兩題也可以拿來練習使用二分搜尋法哦 [first-bad-version](https://leetcode.com/problems/first-bad-version/) [search-insert-position](https://leetcode.com/problems/search-insert-position/) By. @joe94113
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.