二分查找算法詳講(三種版本寫法)原創

介紹:

二分查找算法(Binary Search)是一種在有序數組中查找目標元素的算法。
它的基本思想是通過將目標元素與數組的中間元素進行比較,從而將搜索范圍縮小一半。

  • 如果目標元素等于中間元素,則搜索結束;
  • 如果目標元素小于中間元素,則繼續在左半部分查找;
  • 如果目標元素大于中間元素,則在右半部分查找。

通過不斷地將搜索范圍縮小一半,最終可以找到目標元素或確定目標元素不存在。

接下來通過例題介紹二分的不同寫法

例題:

輸入一個整數 n, 接下來一行輸入 n 個整數(保證整數序列有序), 最后輸入一個整數 m, 查找 m 在序列中的起始下標和結束下標

示例1:

輸入:

5
1 2 2 4 5
2

輸出:

1 2

解釋:

2 在序列中的起始和結束位置是下標 1 和 2

代碼講解:

二分代碼按照退出條件分為

  1. while (l <= r)
  2. while (l < r)

代碼中的所有 lr 都是序列的左右閉區間

代碼中的所有 l + r >> 1l + r + 1 >> 1 分別相當于 (l + r) / 2(l + r + 1) / 2>>是按位右移, 整數向右位移一位相當于除2

代碼中的所有 x, 都是目標值, 也就是要查找的值; 所有的 idx, 是答案, 也就是要查找數的起始下標或結束下標

先講第一種: while (l <= r), 在l > r時退出

// 查找起始下標
int l = 0, r = n - 1, idx = 0;
while (l <= r)
{int mid = l + r >> 1;  // 一分為3, [l, mid), [mid, mid], (mid, r]if (a[mid] < x) l = mid + 1;  // 如果當前中間值比 x 小, 需要去序列的右區間, 因為mid位置的數比 x 小, 那么左邊的區間(l, mid]的所有數都比 x 小else if (a[mid] > x) r = mid - 1;  // 同上else if (a[mid] == x)  // 等于答案時{idx = mid;r = mid - 1;  // 我們要找的時起始的下標, 雖然此時a[mid] == x, 但是mid的左邊可能還有等于x的值, 所以我們要繼續往左區間去找}
}// 查找結束下標(代碼中只有注釋的地方和上面的代碼不一樣)
int l = 0, r = n - 1, idx = 0;
while (l <= r)
{int mid = l + r >> 1;  // 一分為3, [l, mid), [mid, mid], (mid, r]if (a[mid] < x) l = mid + 1;  else if (a[mid] > x) r = mid - 1;  else if (a[mid] == x)  {idx = mid;l = mid + 1;  // 我們要找的時結束的下標, 雖然此時a[mid] == x, 但是mid的右邊可能還有等于x的值, 所以我們要繼續往右區間去找}
}

觀察上面代碼我們可以把a[mid] == x的情況跟其他兩種情況合并

// 查找起始下標
int l = 0, r = n - 1, idx = 0;
while (l <= r)
{int mid = l + r >> 1;  // 一分為3, [l, mid), [mid, mid], (mid, r]if (a[mid] < x) l = mid + 1;  else if (a[mid] >= x){idx = mid;r = mid - 1;  // 繼續往左區間找}
}// 查找結束下標
int l = 0, r = n - 1, idx = 0;
while (l <= r)
{int mid = l + r >> 1;if (a[mid] <= x){idx = mid;l = mid + 1;  // 繼續往右區間找}else if (a[mid] > x) r = mid - 1;
}

下面講第二種: while (l < r) 在l == r時退出

大家可以發現這種寫法不需要 idx 這個變量來記錄最終查找的x的起始下標或結束下標了, 因為最后l就是對應的起始下標或結束下標。(r等于l, 所以用r也行)

查找起始下標
int l = 0, r = n - 1;
while (l < r)
{int mid = l + r >> 1;  // 區間分成了兩個 [l, mid] 和 (mid, r]if (a[mid] < x) l = mid + 1;// 當a[mid] == x的時候, r一直往左, 所以當有多個相同的x的話, 會查找到第一個else if (a[mid] >= x) r = mid;  // 因為a[mid]可能 == x, 因為mid也可能滿足條件, 所以區間變成[l, mid]
}查找結束下標
int l = 0, r = n - 1, idx = 0;
while (l < r)
{				int mid = l + r + 1 >> 1;  // 區間分成了兩個 [l, mid) 和 [mid, r]if (a[mid] > x) r = mid - 1;// 當a[mid] == x的時候, l一直往右, 所以當有多個相同的x的話, 會查找到最后一個else if (a[mid] <= x) l = mid;  // 因為a[mid]可能 == x, 因為mid也可能滿足條件, 所以區間變成[mid, r]
}

接下來講一下第二種查找結束下標的時候 為什么是 mid = l + r + 1 >> 1,而不是 mid = l + r >> 1;
c++默認向0取整, 對于正整數你可以說是向下取整, 也就是 5 / 2 = 2,
當出現 l = r - 1 的時候, 此時 mid = (l + r) / 2 向下取整后等于 r - 1 , 如果此時進入了a[mid] <= x的分支, 那么 l = mid = r - 1, 這時會發現 l 沒有發生變化, 那么就會一直陷入死循環

先更到這里, 后面再補充

覺得寫的不錯的話, 點個贊吧

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18464.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18464.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18464.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Neural Filters:照片恢復

Ps菜單&#xff1a;濾鏡/Neural Filters/恢復/照片恢復 Neural Filters/RESTORATION/Photo Restoration 照片恢復 Photo Restoration借助 AI 強大功能快速恢復舊照片&#xff0c;提高對比度、增強細節、消除劃痕。將此濾鏡與著色相結合以進一步增強效果。 “照片恢復”濾鏡利用…

Scikit-Learn隨機森林

Scikit-Learn隨機森林 1、隨機森林1.1、集成學習1.2、Bagging方法1.3、隨機森林算法1.4、隨機森林的優缺點2、Scikit-Learn隨機森林回歸2.1、Scikit-Learn隨機森林回歸API2.2、隨機森林回歸實踐(加州房價預測)1、隨機森林 隨機森林是一種由決策樹構成的集成算法,它在大多情況…

mac安裝的VMware虛擬機進行橋接模式配置

1、先進行網絡適配器選擇&#xff0c;選擇橋接模式 2、點擊網絡適配器 設置... 3、選擇WiFi&#xff08;我使用的是WiFi&#xff0c;所以選擇這個&#xff09;&#xff0c;注意看右邊的信息&#xff1a;IP和子網掩碼&#xff0c;后續配置虛擬機的ifcfg-ens文件會用到 4、編輯if…

【論文閱讀筆記】The Google File System

1 簡介 Google File System (GFS) 是一個可擴展的分布式文件系統&#xff0c;專為快速增長的Google數據處理需求而設計。這篇論文發表于2003年&#xff0c;此前已在Google內部大規模應用。 GFS不僅追求性能、可伸縮性、可靠性和可用性等傳統分布式文件系統的設計目標&#xf…

benchmark::State benchmark 原理

benchmark::State benchmark::State是Google Benchmark庫中的一個核心類&#xff0c;用于管理單個基準測試的狀態信息和控制基準測試的執行流程。在編寫基準測試時&#xff0c;這個類提供了一套豐富的接口&#xff0c;允許用戶獲取測試循環的次數、調整測試參數、測量時間等&a…

P9 【力扣+知識點】【算法】【二分查找】C++版

【704】二分查找&#xff08;模板題&#xff09;看到復雜度logN&#xff0c;得想到二分 給定一個 n 個元素有序的&#xff08;升序&#xff09;整型數組 nums 和一個目標值 target &#xff0c;寫一個函數搜索 nums 中的 target&#xff0c;如果目標值存在返回下標&#xff0…

企業微信hook接口協議,ipad協議http,語音轉文字

語音轉文字 參數名必選類型說明uuid是String每個實例的唯一標識&#xff0c;根據uuid操作具體企業微信msgid是int要轉文字的語音消息id 請求示例 {"uuid":"a4ea6a39-4b3a-4098-a250-2a07bef57355","msgid":1063645 } 返回示例 {"data&…

電源模塊測試系統怎么測試輸入電壓范圍?

在現代電子設備中&#xff0c;電源模塊的性能直接影響著整個系統的穩定性和效率。其中&#xff0c;電源輸入電壓范圍是指電源能夠接受的輸入電壓的最小值和最大值&#xff0c;它是確保電源正常工作的重要參數。為了提高測試效率和精度&#xff0c;自動化的測試方法逐漸取代了傳…

【Game】Rumble Heroes

文章目錄 1 英雄2 守護獸3 符文4 祝福5 陣容推薦6 Boss7 兌換碼 1 英雄 &#xff08;1&#xff09;力量 神話英雄 圣騎士-烏瑟爾 傳說英雄 雙刀-宮本武藏死亡騎士-阿薩斯冰霜騎士-亞瑟疾風焰刃-緣壹熊貓武僧-阿寶 史詩英雄 大劍-克勞德狂戰士-奎托斯魔山-克里剛獵人-奈辛瓦里 稀…

寶塔部署Java+Vue前后端分離項目

1. 服務器 服務器選擇Linux的CentOS7的版本 2. 寶塔Linux面板 2.1 百度搜索寶塔 2.2 進去之后點擊立即免費安裝 2.3 選擇Linux在線安裝&#xff0c;輸入服務器信息進行安裝(也可以選擇其他方式) 安裝完成之后會彈一個寶塔的應用面板&#xff0c;并附帶有登錄名稱和密碼&…

多模態大模型:系統、趨勢與問題

引言 多模態大模型是當今人工智能領域的熱門方向之一。它不僅能處理文本&#xff0c;還能理解和生成圖像、視頻、語音等多種模態的數據。這種能力使得多模態大模型在自然語言處理、計算機視覺等多個領域展示出巨大的潛力和應用價值。那么&#xff0c;多模態大模型是如何訓練出…

AI菜鳥向前飛 — LangChain系列之十五 - Agent系列:從現象看機制(中篇)一個Agent的“旅行”

Agent基本架構 先談談Agent基本架構概念&#xff0c;如果看得云里霧里&#xff0c;等看完本篇之后&#xff0c;再回頭看就會豁然開朗的&#xff0c;而我盡量寫得更易懂&#xff1a; &#xff09; 這里面會穿插著上一篇的內容&#xff0c;請大家記得往回翻翻&#xff0c;傳送門&…

MySQL 慢查詢優化指南

MySQL 慢查詢優化指南 在現代數據庫管理中&#xff0c;性能優化是一個不可忽視的重要環節。尤其是對于高并發、大數據量的應用&#xff0c;慢查詢可能會成為系統的性能瓶頸。本文將介紹如何查看和優化 MySQL 的慢查詢&#xff0c;幫助你提高數據庫性能。 一、什么是慢查詢&am…

C語言 | Leetcode C語言題解之第118題楊輝三角

題目&#xff1a; 題解&#xff1a; int** generate(int numRows, int* returnSize, int** returnColumnSizes) {int** ret malloc(sizeof(int*) * numRows);*returnSize numRows;*returnColumnSizes malloc(sizeof(int) * numRows);for (int i 0; i < numRows; i) {re…

C#實現計算數據和刷新ListView列表并發執行

下面是一個示例代碼&#xff0c;演示如何在C#中實現計算列表的數據和刷新ListView控件的數據的并發執行&#xff1a; using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms;class Program {static List<int> dataList …

前端API: IntersectionObserver的那一二三件事

IntersectionObserver 基礎 IntersectionObserver 可以監聽一個元素和可視區域相交部分的比例&#xff0c;然后在可視比例達到某個閾值的時候觸發回調。比如可以用來處理圖片的懶加載等等 首先我們來看下基本的格式&#xff1a; const observer new IntersectionObserver(c…

yolov10 使用自己的數據集訓練目標檢測模型

1 環境配置(使用anaconda) conda create -n yolov10 python=3.9 //創建虛擬環境 conda activate yolov10 //激活虛擬環境 pip install -r requirements.txt //執行yolov10 路徑下requirements.txt 安裝依賴 pip install -e .2.數據集制作 使用lableImage制作數據集(win版…

華為云Astro Zero低代碼平臺案例:小、輕、快、準助力銷售作戰數字化經營

客戶背景&#xff1a; 隨著業務的不斷擴展&#xff0c;華為云某一線作戰團隊發現&#xff0c;原本基于線上Excel的項目跟蹤方式面臨新的挑戰&#xff1a;多區域、多場景下的業務管理越來越復雜&#xff0c;項目管道存在多種不可控因素&#xff0c;客戶關系、進展跟蹤同步不及時…

【Qt秘籍】[003]-Qt環境變量配置-磨刀不誤砍柴工

一、為什么要設置環境變量 &#xff1f;[原因] 配置PATH環境變量的主要用處在于讓操作系統能夠識別并執行不在當前工作目錄下的可執行文件。具體來說&#xff0c;它的作用包括&#xff1a; 命令執行便捷性&#xff1a;當你在命令行輸入一個命令&#xff08;如java, python或np…

【Unity程序】Unity游戲開發中常用的設計模式【一】

&#x1f468;?&#x1f4bb;個人主頁&#xff1a;元宇宙-秩沅 &#x1f468;?&#x1f4bb; hallo 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;?&#x1f4bb; 本文由 秩沅 原創 &#x1f468;?&#x1f4bb; 收錄于專欄&#xff1a;Uni…