CC53.【C++ Cont】二分查找的普通模版

目錄

1.知識回顧

2.關鍵點

特點

三個模版

普通的模版(有局限)

以LeetCode上的一道題為例:704. 二分查找

分析

引入二段性:分兩段,舍一段,操作另一段(這個是二分查找的本質!)

代碼

提交結果

當然也可以使用隨機數來分兩段

普通模版總結


1.知識回顧

之前在C語言專欄中的文章提到了二分查找,可復習:

E7.【C語言】練習:在一個有序數組中查找具體的某個數字n(二分查找)

本文將提煉出一些關鍵點

2.關鍵點

特點

算法細節較多,一 一介紹:

之前講過二分查找的前提: 數組有序時才能使用二分查找,其實并不是這樣!,

當數組滿足某特定規律時,也可以使用二分查找(這個后面會介紹)

三個模版

有以下二分查找的固定格式,做題只需要照葫蘆畫瓢,注意先理解再記憶

普通的模版(有局限)

以LeetCode上的一道題為例:704. 二分查找

https://leetcode.cn/problems/binary-search/description/

給定一個?n?個元素有序的(升序)整型數組?nums 和一個目標值?target ?,寫一個函數搜索?nums?中的 target,如果目標值存在返回下標,否則返回 -1
示例 1:

輸入: nums = [-1,0,3,5,9,12], target = 9
輸出: 4
解釋: 9 出現在 nums 中并且下標為 4

示例?2:

輸入: nums = [-1,0,3,5,9,12], target = 2
輸出: -1
解釋: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假設 nums?中的所有元素是不重復的。
  2. n?將在?[1, 10000]之間。
  3. nums?的每個元素都將在?[-9999, 9999]之間。
分析

暴力解法直接從左向右或從右向左找,這里不寫,講講暴力解法的缺陷:每次只能比較一個數,時間復雜度為O(N)

注意到題目條件"一個?n?個元素有序的(升序)整型數組?nums ",那么可以利用數組的單調性對暴力解法優化

以nums = [-1,0,3,5,9,12], target = 9為例說明,現查找到3,發現target>3且數組單增,那么3的左側是不需要查找的,繼續查找3的右側

引入二段性:分兩段,舍一段,操作另一段(這個是二分查找的本質!)

對于上述單增數組有許多分段方式:

1.二分

即近似分成二等分

2.三分

將數組近似分成三等分

然后任意選一個節點來分段,例如:

3.四分

將數組近似分成四等分......

......

當然也可以使用隨機數來分段

其中二分的時間復雜度是最低的,時間復雜度為O(logN),當然某些情況下使用隨機數來分段時間復雜度也比較低

算法:設數組是單調遞增的,對它平分兩段:

比較nums[mid]和num[target]的大小,

1.nums[mid]==num[target],結束循環,返回結果

2.nums[mid]<num[target],依據二段性:分兩段,舍一段,操作另一段

,舍棄[left,mid]段,去[mid,right]段尋找,那么更新left

left=mid+1;//right不變

nums[mid]>num[target],返回結果,依據二段性:分兩段,舍一段,操作另一段

,舍棄[mid,right]段,去[left,mid]段,那么更新right

right=mid-1;//left不變

3.更新mid(有多種方法,上面提過了)

只需要循環上面三步,變化尋找的區間,最終一定可以找到結果

結束循環的兩個條件:

1.nums[mid]==num[target],直接返回結果

2.left>right,(注:left==right,分的段是一個"點",只有一個元素,但也需要判斷是否等于target,仍然需要循環),沒有找到target

那么循環的條件是:left\leqslantright

代碼
class Solution {
public:int search(vector<int>& nums, int target) {int left=0;int right=nums.size()-1;int mid;while(left<=right){mid=left+(right-left+1)/2;if (nums[mid]==target)return mid;if (nums[mid]>target)right=mid-1;if (nums[mid]<target)left=mid+1;  }return -1;//沒找到target}
};

注:mid不要寫成(left+right)/2!之前在L42.【LeetCode題解】四數之和(雙指針思想) 從匯編角度分析報錯原因文章提到過報錯的原因,當數組過長時,加法可能導致溢出

防溢出的方法:(left+right)/2改為left+(right-left)/2或left+(right-left+1)/2

提交結果

同理三分法只需要將除數2改成3即可,四分法、五分法同理

mid=left+(right-left+1)/3;
當然也可以使用隨機數來分兩段
class Solution {
public:int search(vector<int>& nums, int target) {srand((unsigned int)time(nullptr));int left=0;int right=nums.size()-1;int mid;while(left<=right){mid=left+rand()%(right - left + 1);if (nums[mid]==target)return mid;if (nums[mid]>target)right=mid-1;if (nums[mid]<target)left=mid+1;   }return -1;}
};

注: 循環體中,如果最后更新mid將導致除0錯誤!

這樣寫是錯誤的:

class Solution {
public:int search(vector<int>& nums, int target) {srand((unsigned int)time(nullptr));int left=0;int right=nums.size()-1;int mid=left+rand()%(right - left + 1);while(left<=right){if (nums[mid]==target)return mid;if (nums[mid]>target)right=mid-1;if (nums[mid]<target)left=mid+1;mid=left+rand()%(right - left + 1);   }return -1;}
};

排查錯誤:

VS中進入調試模式

發生錯誤的地方是:?mid = left + rand() % (right - left + 1),則mid=2+rand()%(1-2+1)=2+rand()%0,為除0錯誤,此時left仍然<=right,策略:先更新mid的值,這樣進行if判斷時能修改left和right的值,能及時退出循環,防止除0錯誤

提交結果:

普通模版總結

利用二段性填以下模版空缺的地方:

while(left<=right)
{int mid=left+(right-left+1)/2;if (......)return mid;if (......)right=mid-1;if (......)left=mid+1;  
}

注意1.判斷條件 2.mid防溢出方法 3.left和right的更新方式

其他兩個模版見下一篇文章

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

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

相關文章

lua腳本+Redission實現分布式鎖

實現分布式鎖最簡單的一種方式&#xff1a;基于Redis 不論是本地鎖還是分布式鎖&#xff0c;核心都在于“互斥”。 在 Redis 中&#xff0c; SETNX 命令是可以幫助我們實現互斥。SETNX 即 set if not exists (對應 Java 中的 setIfAbsent 方法)&#xff0c;如果 key 不存在的…

設計模式之工廠模式(二):實際案例

設計模式之工廠模式(一) 在閱讀Qt網絡部分源碼時候&#xff0c;發現在某處運用了工廠模式&#xff0c;而且編程技巧也用的好&#xff0c;于是就想分享出來&#xff0c;供大家參考&#xff0c;理解的不對的地方請多多指點。 以下是我整理出來的類圖&#xff1a; 關鍵說明&#x…

MultiTTS 1.7.6 | 最強離線語音引擎,提供多音色無障礙朗讀功能,附帶語音包

MultiTTS是一款免費且支持離線使用的文本轉語音&#xff08;TTS&#xff09;工具&#xff0c;旨在為用戶提供豐富的語音包選項&#xff0c;實現多音色無障礙朗讀功能。這款應用程序特別適合用于閱讀軟件中的離線聽書體驗&#xff0c;提供了多樣化的語音選擇&#xff0c;使得聽書…

歌曲《忘塵谷》基于C語言的歌曲調性檢測技術解析

引言 在音樂分析與數字信號處理領域&#xff0c;自動檢測歌曲調性是一項基礎且關鍵的任務。本文以C語言為核心&#xff0c;結合音頻處理庫&#xff08;libsndfile&#xff09;和快速傅里葉變換庫&#xff08;FFTW&#xff09;&#xff0c;探討如何實現調性檢測&#xff0c;并通…

大某麥演唱會門票如何自動搶

引言 僅供學習研究&#xff0c;歡迎交流 搶票難&#xff0c;難于上青天&#xff01;無論是演唱會、話劇還是體育賽事&#xff0c;大麥網的票總是秒光。大麥網是國內知名的票務平臺&#xff0c;熱門演出票往往一票難求。手動搶票不僅耗時&#xff0c;還容易錯過機會。作為一名…

1.3.3 tinyalsa詳細介紹

一、TinyALSA 的背景與設計目標 1. 誕生背景 Android 音頻需求的演變&#xff1a;早期 Android 系統使用標準 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09;的用戶空間庫 alsa-lib&#xff0c;但因其復雜性&#xff08;代碼龐大、依賴較多&#xff09;和資…

超越合并速度(merge speed):AI如何重塑開發者協作

李升偉 編譯 AI 關于現代開發的討論通常圍繞著單一指標&#xff1a;合并速度&#xff08;merge speed&#xff09;。但在這一表面測量之下&#xff0c;隱藏著開發團隊工作方式的一種更深刻的變革。讓我們探討開發者協作的微妙演變方式以及為什么傳統生產力指標只講述了一部分故…

如何找正常運行虛擬機

1.新建虛擬機。Linux centos7&#xff0c;給虛擬機改個名字不要放在c盤 2.安裝操作系統。cd/dvd->2009.iso 啟動虛擬機

深度學習:系統性學習策略(二)

深度學習的系統性學習策略 基于《認知覺醒》與《認知驅動》的核心方法論,結合深度學習的研究實踐,從認知與技能雙重維度總結以下系統性學習策略: 一、認知覺醒:構建深度學習的思維操作系統 三重腦區協同法則 遵循**本能腦(舒適區)-情緒腦(拉伸區)-理智腦(困難區)**的…

如何使用CSS解決一行有三個元素,前兩個元素靠左排列,第三個元素靠右排列的問題

如圖所示&#xff0c;我要把左邊的場館和區域信息靠左排列&#xff0c;價格信息靠右排列。如何使用CSS實現這種效果&#xff1f; 在這里&#xff0c;我使用了flexbox彈性布局&#xff0c;以下是我的實現代碼 .name-info {display: flex;gap: 2px;justify-content: space-betwee…

USB傳輸模式

USB有四種傳輸模式: 控制傳輸, 中斷傳輸, 同步傳輸, 批量傳輸 1. 中斷傳輸 中斷傳輸一般用于小批量, 非連續的傳輸. 對實時性要求較高. 常見的使用此傳輸模式的設備有: 鼠標, 鍵盤等. 要注意的是, 這里的 “中斷” 和我們常見的中斷概念有差異. Linux中的中斷是設備主動發起的…

【Python 變量類型】

Python 是一種動態類型語言&#xff0c;變量類型在運行時自動確定&#xff0c;無需顯式聲明。以下是 Python 中核心變量類型的分類與用法詳解&#xff1a; 一、基本數據類型 1. 數值類型 整數 (int) 支持正負數、零和二進制/八進制/十六進制表示&#xff1a; a 42 b 0o52 #…

Python基礎:類的深拷貝與淺拷貝-->with語句的使用及三個庫:matplotlib基本畫圖-->pandas之Series創建

一.類的深拷貝與淺拷貝 class CPU():pass class Disk():passclass Computer():#計算機由CPU和硬盤組成def __init__(self):self.cpu CPU()self.disk Disk()cpu CPU()#創建一個CPU對象 disk Disk()#創建一個硬盤對象#創建一個計算機對象 com Computer(cpu,disk) #變量&…

【SSM-SpringMVC(二)】Spring接入Web環境!本篇開始研究SpringMVC的使用!SpringMVC數據響應和獲取請求數據

SpringMVC的數據響應方式 頁面跳轉 直接返回字符串通過ModelAndView對象返回 回寫數據 直接返回字符串返回對象或集合 頁面跳轉&#xff1a; 返回字符串方式 直接返回字符串&#xff1a;此種方式會將返回的字符串與視圖解析器的前后綴拼接后跳轉 RequestMapping("/con&…

閱文集團C++面試題及參考答案

目錄 能否不使用鎖保證多線程安全? 面向對象的三個特性是什么?請分別解釋。 構造函數和析構函數能否被繼承? C++ 中函數重載是如何實現的? C 語言中是否支持函數重載? 什么是左值和右值?請舉例說明。 C++ 中子類的構造和析構順序是怎樣的? C++ 中虛函數表的變化過…

【親測有效】如何清空但不刪除GitHub倉庫中的所有文件(main分支)

如何清空但不刪除GitHub倉庫中的所有文件&#xff08;main分支&#xff09; 在項目開發過程中&#xff0c;有時我們需要清空GitHub倉庫中的所有文件&#xff0c;同時保留倉庫本身。這種情況常見于項目重構、代碼重寫或者需要重新開始一個項目時。本文將介紹一種有效的方法來清…

前端EXCEL插件,智表ZCELL產品V3.0 版本發布,底層采用canvas全部重構,功能大幅擴展,性能極致提升,滿足千萬級單元格加載

本次更新是底層全部重構&#xff0c;按照現代瀏覽器要求&#xff0c;采用canvas方式進行了重構&#xff0c;預留了將來擴展空間&#xff0c;特別是在大數據量性能提升方面有了較大提升&#xff0c;可以滿足千萬級單元格加載&#xff0c;歡迎大家體驗使用。 體驗地址&#xff1…

3DGS-to-PC:3DGS模型一鍵絲滑轉 點云 or Mesh 【Ubuntu 20.04】【2025最新版!!】

一、引言 3D高斯潑濺(3DGS)是一種新興的三維場景表示方法&#xff0c;可以生成高質量的場景重建結果。然而&#xff0c;要查看這些重建場景&#xff0c;需要特殊的高斯渲染器。大多數3D處理軟件并不兼容3D高斯分布模型&#xff0c;但它們通常都兼容點云文件。 3DGS-to-PC項目提…

OpenHarmony 以太網卡熱插拔事件接口無效

目錄 1.背景 2.解決方案 1.背景 在OpenHarmony中調用以太網熱插拔時間,發現熱插拔沒有任何回調,如下接口 import { ethernet } from @kit.NetworkKit;ethernet.on(interfaceStateChange, (data: object) => {console.log(on interfaceSharingStateChange: + JSON.…

C++ 跨平臺開發挑戰與深度解決方案:從架構設計到實戰優化

C 憑借其高性能與底層控制能力&#xff0c;在游戲引擎、嵌入式系統、工業軟件等領域占據核心地位。然而&#xff0c;跨平臺開發過程中需應對硬件架構多樣性、操作系統差異性、編譯工具鏈碎片化等復雜問題。本文將從底層架構到上層應用&#xff0c;系統性剖析 C 跨平臺開發的核心…