二元搜尋 (下) 技巧與應用

JN-avatar-img
發佈於計算機
更新 發佈閱讀 7 分鐘


這篇是分享個人在實作 binary search 時,讓它變得更實用的技巧。

如上篇網友留言,在 AI 時代這些技巧已沒那麼重要,有興趣的網友把這篇當飯後故事看即可。

直接進入主題。

先看上篇教科書版的 binary_search code,

def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1

可以看到它的功能是:

  1. 找不到 target 時是會 return -1,
  2. 若 arr 裡有不只一個數字符合 target,會回傳最先找到的 index


我的技巧是在功能的定義做點修正,將改良版 binary_search 規定為:

  1. 若找不到 target,return 它該出現的 index
  2. 若 arr 裡不只一個數字符合 target,回傳第一個的 index


先舉幾個例子幫助理解,

arr = [1, 1, 3, 3, 5, 7, 7],

  • binary_search(arr, 3)
    • returns 2
    • 回傳第一個 3 的 index
  • binary_search(arr, 7)
    • returns 5
    • 回傳第一個 7 的 index
  • binary_search(arr, 8)
    • returns 7
    • arr 內沒有 8,回傳 8 在 arr 裡該出現的 index
  • binary_search(arr, 0)
    • returns 0
    • arr 內沒有 0,回傳 0 在 arr 裡該出現的 index


接續上篇的情境來解釋實用在哪,最後再講實作。


學姊為何要換衣服?為何要綁頭髮?為何呢...

學姊為何要換衣服?為何要綁頭髮?為何呢...


第一種用法,
就是上篇的用法,找出某尺寸的鞋。

arr = [2, 6, 6, 14, 15, 25, 27, 29, 30, 42]
target = 25
index = binary_search(arr, target)

if arr[index] == target:
print(f"找到啦! {target} 號鞋的 index 是 {index}")
else:
print(f"沒有 {target} 號鞋..")

執行結果

$ python binary_search.py
找到啦! 25 號鞋的 index 是 5

若把 target 改成 28

$ python binary_search.py
沒有 28 號鞋..


第二種用法,
拿到新一盒鞋子,要放進排好的盒堆中,並保持順序。

arr = [2, 6, 6, 14, 15, 25, 27, 29, 30, 42]
target = 26
index = binary_search(arr, target)
print(f"{target} 號鞋請放在 index = {index} 的位子!")

執行結果

$ python binary_search.py
26 號鞋請放在 index = 6 的位子!


第三種用法,
若乾爹想要買下某尺寸全部的鞋,可以很快地幫他取出來。

arr = [2, 6, 25, 25, 25, 25, 25, 29, 30, 30]
tar = 25

idx1 = binary_search(arr, target)

if arr[idx1] != tar:
print(f"沒有 {tar} 號鞋 >///<'")
else:
# 找大一號的鞋子,再把 index 減 1
idx2 = binary_search(arr, tar + 1) - 1
print(f"所有 {tar} 號鞋放在 index {idx1} 到 {idx2} 的位子!")

執行結果

$ python binary_search.py
所有 25 號鞋放在 index 26 的位子!

將 target 改成 31

$ python binary_search.py
沒有 31 號鞋 >///<'


以上簡單分享三種用法,只要將 binary_search 定義清楚,就能這樣應用。


再複習一次改良版 binary_search 定義:

  1. 若找不到 target,return 它該出現的 index
  2. 若 arr 裡不只一個數字符合 target,回傳第一個的 index


接下來是實作,其實也不難,概念都一樣。

def binary_search(arr, target):
low, high = 0, len(arr)
while low < high:
mid = (low + high) // 2
if arr[mid] < target:
low = mid + 1
elif arr[mid] > target:
high = mid
else:
high = mid
return low


跟上篇的版本非常類似,留給有興趣的讀者慢慢理解,歡迎留言討論。



Gemini...

真懂我...

真懂我...



偷偷抱怨一下,

code block 真D難用...




留言
avatar-img
留言分享你的想法!
avatar-img
JN的沙龍
63會員
34內容數
個人網誌啦~ 內容包含但不限於學習筆記、心情抒發、火星廢文...
JN的沙龍的其他內容
2025/08/08
年少不知姐姐好...
Thumbnail
2025/08/08
年少不知姐姐好...
Thumbnail
2025/01/17
某天,某島國上的花生農老G,因為體力漸衰、氣候異常、地緣政治...等因素,種出的花生品質越來越不穩定,於是邀了其他島上的A格斯先生、高手B爾、阿國兄,四人一起組了個互助會...
Thumbnail
2025/01/17
某天,某島國上的花生農老G,因為體力漸衰、氣候異常、地緣政治...等因素,種出的花生品質越來越不穩定,於是邀了其他島上的A格斯先生、高手B爾、阿國兄,四人一起組了個互助會...
Thumbnail
2025/01/13
下圖為程式碼節錄 把 output 印出來看,會發現有五組數字,每一組數字依序對應到驗證碼圖片
Thumbnail
2025/01/13
下圖為程式碼節錄 把 output 印出來看,會發現有五組數字,每一組數字依序對應到驗證碼圖片
Thumbnail
看更多
你可能也想看
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
中學數學基礎練習—二元一次方程式
Thumbnail
中學數學基礎練習—二元一次方程式
Thumbnail
中學數學基礎練習—二元一次方程式
Thumbnail
中學數學基礎練習—二元一次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元二次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News