iT邦幫忙

2021 iThome 鐵人賽

DAY 18
1

生活上我們可能有遇過一些二分搜尋的例子。
例如以前如果有當過助教的經驗,有時候我們在收學生作業時會作業按照學號由小到大排好,
假設有100位學生001~100,我們要找第69號,我們可能會大概拆分成兩疊在從後面那一疊,而非從頭開始慢慢算,這就是二分搜尋的生活例子!

從這個例子中可以發現,如果我們今天要從已經排列好的東西找到想要的結果
→ 我們都可以想想二分搜尋是否可以派上用場!

那我們來看看這題題目吧!

Input: nums = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in nums and its index is 4

今天拿nums = [-1,0,3,5,9,12] ,我們想要尋找9是否在nums內,如果有救回傳他的index,沒有則回傳-1。
一開始我們要出中位數的index,我們先建立一個左指標和右指標分別指向nums的頭和尾,計算中間值index。
https://ithelp.ithome.com.tw/upload/images/20211003/20141729XJn66q4sVr.png

(0+5)/2 無條件捨去法,得到2。
我們得到 nums[2] 為 3,又因 3 < 9 ,所以我們知道9的index一定是在2的右手邊
於是我們就可以忽略 index 從 0 到 2的元素!直接從 index=3開始尋找,所以我們把左指標移到了 nums[3]
https://ithelp.ithome.com.tw/upload/images/20211003/20141729Th2ckDwBwK.png
一樣找中間index
( 3 + 5 ) / 2 = 4
nums[4] = 9 於是我們找到了9的index為4

以上就是二分搜尋。

那如果我們要尋找的數不在陣列中會發生什麼事?
我們一樣用同樣得陣列來尋找 target = 10
我們接著nums[4] = 9,所以10的index一定會在4的右手邊。
我們要把左指標移到index為5的位置,這時候發現左邊跟右邊的指標指向同一個位置了!
但是 nums[5] = 12≠10 對吧?
又因為 10 < 12
這時候我們想要把右指標移動到 index 為 5 - 1 = 4
但這樣卻變成右邊指標跑道左邊指摽的左手邊了!
這時我們就可以理所當然地停止搜尋,也就是這個數根本存在!
時間複雜度為 O(logN)
空間複雜度方面,則牽涉到我們的實作方式有關。

如果是用iteratively的方式,Space可以為O(1),只需要紀錄中間index
如果是recursively的方式,用到stack的資料結構,就會讓Space變成O(logN)

讓我們來看一下兩種方式的實作吧!

// iteratively
var search = function (nums, target) {
  return binarySearchMethod(nums, target, 0, nums.length - 1);
};

const binarySearchMethod = (array, target, left, right) => {
  while (left <= right) {
    const midIndex = Math.floor((left + right) / 2);
    const midNumber = array[midIndex];
    if (target === midNumber) {
      return midIndex;
    } else if (target < midNumber) {
      right = midIndex - 1;
    } else {
      left = midIndex + 1;
    }
  }
  return -1;
};

//recursively

var search = function (nums, target) {
  return binarySearchMethod(nums, target, 0, nums.length - 1);
};
const binarySearchMethod = (array, target, left, right) => {
  if (right < left) return -1;
  const midIndex = Math.floor((left + right) / 2);
  const midNumber = array[midIndex];
  if (target === midNumber) {
    return midIndex;
  } else if (target < midNumber) {
    return binarySearchMethod(array, target, left, midIndex - 1);
  } else {
    return binarySearchMethod(array, target, midIndex + 1, right);
  }
};

明天題目預告: 二元樹的三種走訪 BST Traversal


上一篇
Day 17 : Add Two Numbers
下一篇
Day 19:二元樹遍歷 Binary Tree Traversal
系列文
30天用JavaScript刷題刷起來!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言