二分查找大集合(媽媽再也不用擔心我的二分查找了)

2021-02-21 算法與數據結構

來自:韓子遲 - 博客園

作者:韓子遲【github:https://github.com/hanzichi 求關注】

連結:http://www.cnblogs.com/zichi/p/5118032.html

已獲轉載授權

什麼是二分查找就不多說了。

有時經常會碰到類似於從一個有序數組中找到元素第一次出現的位置,求一個有序數組中小於某元素的個數,將一個元素插入一個有序數組中,等等這樣的需求。比如 leetcode 315. Count of Smaller Numbers After Self 這道題用二分查找來解,就需要維護一個有序數組,不斷往數組中添加元素。這樣,傳統的 "從一個有序數組中求一個元素的位置,有則返回,沒有則返回 -1",就需要變一下型了。

當然這完全可以用傳統的二分查找,找到一個相對來說 "比較正確" 的位置,然後從這個位置向左向右擴展,完全可以,而且複雜度也基本是一樣的,不過這樣的實現太 ugly 了。

為了以後能不用每次遇到二分查找就要推下解,特記錄如下,媽媽再也不用擔心我的二分查找了。

第一次出現某數的位置

如果沒找到,則返回 -1

可應對數據重複或者不重複兩種情況

a 數組需正序排列

二分代碼:

function binarySearch(a, target) {

  var start = 0

    , end = a.length - 1;

  while(start <= end) {

    var mid = ~~((start + end) >> 1);

    if (a[mid] >= target)

      end = mid - 1;

    else 

      start = mid + 1;

  }

  return a[start] === target ? start : -1;

}

start 的最終結果永遠比 end 大 1。下同。

測試程序:

function _binarySearch(a, target) {

  for (var i = 0, len = a.length; i < len; i++) {

    if (a[i] === target)

      return i;

    if (a[i] > target)

      return -1;

  }

  return -1;

}

最後一次出現某數的位置

換個思路,求有序數組中最後一次出現某數的位置,也就是求 "該數+1"(不管它在不在數列中) 第一次出現的位置 - 1。

function binarySearch(a, target) {

  target += 1;

  var start = 0

    , end = a.length - 1;

  while(start <= end) {

    var mid = ~~((start + end) >> 1);

    if (a[mid] >= target)

      end = mid - 1;

    else 

      start = mid + 1;

  }

  return a[end] === target - 1 ? end : -1;

}

這裡要注意的是找到的 end 索引可能是 -1,但是因為數組是特殊的對象,所以 a["-1"] 返回 undefined,正是利用了這個 hack,使得程序可以一行返回。同時要注意 target 在函數最開始已經自增過,所以需和 target-1 進行大小對比。

測試程序:

function _binarySearch(a, target) {

  for (var i = 0, len = a.length; i < len; i++) {

    if (a[i] === target && a[i + 1] !== target)

      return i;

    if (a[i] > target)

      return -1;

  }

  return -1;

}

剛好比某數大的元素位置

跟求最後一次出現某數的位置類似。

function binarySearch(a, target) {

  target += 1;

  var start = 0

    , end = a.length - 1;

  while(start <= end) {

    var mid = ~~((start + end) >> 1);

    if (a[mid] >= target)

      end = mid - 1;

    else 

      start = mid + 1;

  }

  return start;

}

如 return 的數等於數組的長度,則表示數組內所有元素都比 target 元素小。

測試程序:

function _binarySearch(a, target) {

  for (var i = 0, len = a.length; i < len; i++) {

    if (a[i] > target)

      return i;

  }

  return a.length;

}

剛好比某數小的元素位置

代碼:

function binarySearch(a, target) {

  var start = 0

    , end = a.length - 1;

  while(start <= end) {

    var mid = ~~((start + end) >> 1);

    if (a[mid] >= target)

      end = mid - 1;

    else 

      start = mid + 1;

  }

  return end;

}

如果 return -1,則表示數組中沒有比 target 元素小的元素了(只能去找索引值為-1的元素了),這時要特別注意需要特判。

測試程序:

function _binarySearch(a, target) {

  for (var i = a.length; i--; ) {

    if (a[i] < target)

      return i;

  }

  return -1;

}

總結

暫時只想到這四種應用場景。

測試程序的測試用例:

for (var i = 0; i < 1000; i++) { // 1000 組數據

  var len = ~~(Math.random() * 500); // 數組長度 0-500

  var a = [];

  for (var j = 0; j < len; j++) 

    a.push(~~(Math.random() * 500)); // 數組元素大小 0-500

  a.sort(function(a, b) {return a - b}); // sort

  var target = ~~(Math.random() * 500); // target 元素

  var ans1 = binarySearch(a, target);

  var ans2 = _binarySearch(a, target);

  if (ans1 === ans2)

    console.log('ok');

  else 

    alert('error!');

}

●本文編號136,以後想閱讀這篇文章直接輸入136即可。

●輸入m可以獲取到文章目錄。

更多推薦請看15個技術類公眾微信

涵蓋:程序人生、算法與數據結構、黑客技術與網絡安全、大數據技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。傳播計算機學習經驗、推薦計算機優秀資源:點擊前往《值得關注的15個技術類微信公眾號

點擊閱讀原文,了解野狗

相關焦點

  • 二分查找會更快嗎?Python中的二分查找與線性查找性能測試
    讓我們看看二分查找是如何工作的。首先,我們需要確保列表是有序的。您可以使用.sort()或sorts()對列表進行排序,我使用.sort()在適當的地方修改列表。具有最小值和最大值的列表:當我們做二分查找時,我們從尋找列表中的中間元素開始:中間索引為5,值為9。首先我們要知道9是不是我們要找的數字。記住,我們要找的是15。如果不是,我們檢查它是更高還是更低。在這個例子中,9比15小,所以我們需要設置一個新的最小值點。我們知道我們不再需要擔心列表的下半部分。新的最小點將被設置為列表上部的第一個可能的項。
  • 入門計算機必會的算法——二分查找法
    再舉一個簡單的場景,假設登錄Facebook時,Facebook會驗證是否為自己網站的用戶,那就必然要去資料庫中作比對,如果逐一對比則用戶等待的時間過長,影響用戶體驗,更合乎邏輯的做法是從中間開始查找,這樣就會節約很長的等待時間。2、二分查找法二分查找是一種算法,其輸入是一個有序的元素列表(注意:列表必須是有序的)。
  • 聊聊一看就會一寫就跪的二分查找
    要說哪個算法的知名度較高,二分查找一定排得上號。後來我又在維基百科上發現了這樣一段話:儘管二分查找的基本思想相對簡單,但細節可以令人難以招架 —— 高德納當喬恩·本特利將二分查找問題布置給專業編程課的學生時,90%的學生在花費數小時後還是無法給出正確的解答,主要因為這些錯誤程序在面對邊界值的時候無法運行,或返回錯誤結果。1988年開展的一項研究顯示,20本教科書裡只有5本正確實現了二分查找。
  • 二分查找法(折半查找法)
    /*二分查找法說明:如果搜尋的數列已經有排序,應該儘量利用它們已排序的特性,以減少搜尋比對的次數 ,這是搜尋的基本原
  • 一篇文章讓你了解二分搜索樹的數據結構的實現過程(Java 實現)
    舉個例子:比如對於查找一個數據,在線性結構中如果不知道具體位置的話需要在一堆數據裡一個一個地去尋找;而對於樹結構,因為樹結構分支的形式,各個數據可以存在不同的分支中,在查找時就可以依據這些分支快速地找到想要的數據。
  • JAVA編程——二分法查找
    一、二分法檢索過程二分法檢索(binary search)又稱折半檢索,二分法檢索的基本思想是設數組中的元素從小到大有序地存放在數組(array)中(註:二分法查找的關鍵,首先數組元素必須從小到大有序排列),(1)首先將給定值 key 與數組中間位置上元素的關鍵碼(key)比較,如果相等,則檢索成功
  • 使用Python和C語言實現二分法查找(折半查找)
    二分查找 叫折半查找,它對要查找的序列有兩個要求,一是該序列必須是有序的,二是該序列必須是順序存儲的。二分法查找算法的原理如下:1、 如果待查對象為空返回-1,表示查找不到目標元素2、 如果待查序列不為空,則將中間元素與要查找的目標元素進行匹配看是否相等,如果相等表示 查找成功,返回該中間元素的索引如果不相等再比較這兩個元素的大小
  • 《一鍵緩存看4K,媽媽再也不用擔心我的視界了》
    前兩天,陸毅在微博裡曬了一臺高定電視,這下鬧大了!陸毅成了國民老公,電視也成了國民電視,而陸毅和電視都成為媽媽們的新寵!  配圖:陸毅微博截圖  經大神級網友查證,陸毅家的電視正是海爾剛發布不久的神器——海爾阿里Ⅱ代電視,  看4K很任性!
  • 【漲姿勢】蘋果削皮切片一體機(媽媽再也不用擔心切蘋果切到手了)
    蘋果削皮切片一體機(媽媽再也不用擔心切蘋果切到手了)漲知識的自覺在下面點個在平臺下拉菜單我要爆料中有網上訂餐功能,歡迎點擊使用。如何關注①查找公眾號:東海縣微平臺②直接添加微信號:dhxwpt晶都網:www.jingduwang.cn 東海最權威新聞門戶網 QQ交流群:261396793
  • iOS新系統上線「查找我的AirPods」功能 像個小型跟蹤器?
    iOS新系統上線「查找我的AirPods」功能 像個小型跟蹤器?  再也不用擔心價值不菲的蘋果無線耳機弄丟了
  • HBO《西部世界》第一季:有趣的二分心智理論
    HBO《西部世界》第一季:有趣的二分心智理論最近不知道該聊什麼,突然就想到了《西部世界》。那麼接下來幾篇就聊聊《西部世界》第一季吧。《西部世界》也是由HBO出品的美劇,非常優秀的一部作品,我一度認為或許它會能與《權力的遊戲》匹敵,不過大家也知道,即便《權力的遊戲》前面七季都很不錯,但是最後還是爛尾了,非常可惜。不過《西部世界》似乎也還是比不上《權力的遊戲》,無論是從口碑還是影響力來說。
  • 二分之派等於多少 cos二分之π等於多少
    二分之π約等於1.5707963,因為π約等於3.1415926,除以2就約等於1.5707963。cos二分之π等於0,sin二分之π等於1。  二分之π是分數嗎  二分之π不是分數,分數是一個整數a和一個正整數b的不等於整數的比。
  • 科技:如何使用「查找我的iPhone」查找丟失的耳機
    導語:很高興大家來到這,今天小編和大家來講講對於蘋果AirPods,如何使用「查找我的iPhone」查找丟失的耳機,快來看看吧!在我們介紹如何找到丟失的Pod之前,您需要注意以下幾點:當充電盒打開或AirPods在盒子外面時,「查找我的iPhone」僅與您的AirPods交互。它們必須位於與iCloud帳戶綁定的iOS設備的藍牙範圍內,才能使當前位置和播放聲音功能正常工作。如果iOS設備不在丟失的AirPod範圍內,「查找我的iPhone」將顯示最後的已知位置。
  • 查找我的iphone在哪裡
    蘋果手機查找我的iPhone在哪裡?近來身邊越來越多的朋友都使用上了蘋果產品,那麼對於長期使用蘋果手機的用戶來說,你知道怎麼打開查找我的iPhone功能呢?不知道的話,就隨便小編一起往下來了解一下吧。查找我的iphone在哪裡:1,點擊蘋果手機的「設置」圖標進入。2,進入設置界面,點擊「隱私」選項,並開啟「定位服務」功能下一步。3,開啟定位服務功能後,返回到設置界面。
  • 分清東南西北的N種大招~媽媽再也不用擔心我迷路了
    分清東南西北的N種大招~媽媽再也不用擔心我迷路了 2020-11-09 16:02 來源:澎湃新聞·澎湃號·政務
  • 「查找我的iphone」,原來這麼強大!
    近日,在國外一名14歲的女生通過手機上的"查找我的Iphone"這個功能立了功。這名女孩將手機放在車裡,而一名男子剛好劫持了這輛車,造成多起交通事故。隨後這名女孩通過"查找我的Iphone"找到了被劫持車輛的位置並告知了警察,隨後警方抓獲了這名竊車賊。
  • 成長是「二分心智」的崩潰與內在敘事的覺醒
    在人類構建內在敘事能力之前,人的決斷與行為依賴於「二分心智」。簡單來說,就是本能與聲音的結合。