二分查找的邊界問題

前言

二分查找(Binary Search)是一種高效的查找算法,時間復雜度為O(log n)。它適用于已排序的數組或列表。本文將詳細介紹二分查找的兩種常見寫法:閉區間寫法和左閉右開區間寫法。

一、二分查找基本思想

二分查找的核心思想是"分而治之":

  1. 將查找區間分成兩部分
  2. 比較中間元素與目標值
  3. 根據比較結果決定繼續在左半部分或右半部分查找
  4. 重復上述過程直到找到目標值或確定目標值不存在

二、閉區間寫法 [left, right]

閉區間寫法中,查找區間包含左右邊界,即[left, right]

代碼實現

#include <vector>
using namespace std;int binarySearchClosed(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1; // 閉區間包含右邊界while (left <= right) { // 1.注意是<=int mid = left + (right - left) / 2; // 2.防止溢出if (nums[mid] == target) {return mid; // 找到目標} else if (nums[mid] < target) {left = mid + 1; // 3.搜索右半部分} else {right = mid - 1; // 4.搜索左半部分}}return -1; // 未找到
}

關鍵點說明

  1. 初始化right = len(nums) - 1,因為要包含最后一個元素

  2. 循環條件left <= right,因為當left == right時區間[left, right]仍然有效

  3. 邊界更新

    • left = mid + 1:因為nums[mid]已經檢查過,可以排除
    • right = mid - 1:同理

三、左閉右開區間寫法 [left, right)

左閉右開區間寫法中,查找區間包含左邊界但不包含右邊界,即[left, right)

代碼實現

int binarySearchLeftClosed(vector<int>& nums, int target) {int left = 0;int right = nums.size(); // 右邊界不包含while (left < right) { // 注意是<int mid = left + (right - left) / 2;if (nums[mid] == target) {return mid;} else if (nums[mid] < target) {left = mid + 1; // 搜索右半部分} else {right = mid; // 注意不是mid-1}}return -1;
}

關鍵點說明

  1. 初始化right = len(nums),因為右邊界不包含

  2. 循環條件left < right,因為當left == right時區間[left, right)無效

  3. 邊界更新

    • left = mid + 1:與閉區間相同
    • right = mid:因為右邊界不包含,所以不需要mid - 1

四、兩種寫法的比較

特性閉區間寫法左閉右開區間寫法
初始化右邊界len(nums)-1len(nums)
循環條件left <= rightleft < right
右邊界更新right = mid - 1right = mid
區間含義[left, right][left, right)
終止條件left > rightleft == right

五、實際應用中的選擇

兩種寫法都是正確的,選擇哪一種主要取決于個人習慣和具體場景:

  1. 閉區間寫法

    • 更直觀,區間定義明確
    • 邊界更新對稱(left=mid+1, right=mid-1)
  2. 左閉右開區間寫法

    • 右邊界初始化更簡單(直接使用nums.size)
    • 在某些變種問題中可能更方便

六、例題展示

例題鏈接:704. 二分查找 - 力扣(LeetCode)
在這里插入圖片描述

解答:

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

七、常見錯誤與注意事項

  1. 溢出問題:計算mid時使用left + (right - left) // 2而不是(left + right) // 2,防止left和right很大時相加溢出
  2. 邊界更新錯誤:確保在左閉右開寫法中不要錯誤地使用right = mid - 1
  3. 循環條件混淆:注意兩種寫法的循環條件不同
  4. 未排序數組:二分查找要求輸入數組必須是有序的

八、總結

二分查找是一種高效且常用的算法,掌握其兩種區間寫法對于解決各種變種問題非常有幫助。理解區間定義和邊界更新規則是關鍵,建議通過大量練習來熟練掌握這兩種寫法。

希望這篇博客能幫助你更好地理解二分查找算法!在實際編程中,可以根據具體情況和個人偏好選擇適合的寫法。

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

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

相關文章

重慶醫科大學附屬第二醫院外科樓外擋墻自動化監測

1.項目概述 重慶醫科大學附屬第二醫院&#xff0c;重醫附二院&#xff0c;是集醫療、教學、科研、預防保健為一體的國家三級甲等綜合醫院。前身為始建于1892年的“重慶寬仁醫院”。醫院現有開放床位 1380張&#xff0c;年門診量超過百萬人次&#xff0c;年收治住院病人4.5萬人…

【Redis實戰篇】秒殺優化

1. 秒殺優化-異步秒殺思路 我們來回顧一下下單流程 當用戶發起請求&#xff0c;此時會請求nginx&#xff0c;nginx會訪問到tomcat&#xff0c;而tomcat中的程序&#xff0c;會進行串行操作&#xff0c;分成如下幾個步驟 1、查詢優惠卷 2、判斷秒殺庫存是否足夠 3、查詢訂單…

【idea】調試篇 idea調試技巧合集

前言&#xff1a;之前博主寫過一篇idea技巧合集的文章&#xff0c;由于技巧過于多了&#xff0c;文章很龐大&#xff0c;所以特地將調試相關的技巧單獨成章, 調試和我們日常開發是息息相關的&#xff0c;用好調試可以事半功倍 文章目錄 1. idea調試異步線程2. idea調試stream流…

postman 用法 LTS

postman 用法 LTS File ---- View ---- Show Postman Console

MySQL 數據庫故障排查指南

MySQL 數據庫故障排查指南 本指南旨在幫助您識別和解決常見的 MySQL 數據庫故障。我們將從問題識別開始&#xff0c;逐步深入到具體的故障類型和排查步驟。 1. 問題識別與信息收集 在開始排查之前&#xff0c;首先需要清晰地了解問題的現象和范圍。 故障現象&#xff1a; 數…

用AI寫簡歷是否可行?

讓AI批量寫簡歷然后投簡歷是絕對不行的&#xff01;&#xff01;&#xff01; 為什么不行&#xff0c;按照 "招聘經理" 工作經歷舉例&#xff1a; ai提示詞&#xff1a;請幫我寫一份招聘經理的工作經歷內容&#xff1a; 招聘經理 | XXX科技有限公司 | 2020年…

【從零實現JsonRpc框架#1】Json庫介紹

1.JsonCpp第三方庫 JSONCPP 是一個開源的 C 庫&#xff0c;用于解析和生成 JSON&#xff08;JavaScript Object Notation&#xff09;數據。它提供了簡單易用的接口&#xff0c;支持 JSON 的序列化和反序列化操作&#xff0c;適用于處理配置文件、網絡通信數據等場景。 2.Jso…

Ubuntu——執行echo $USE什么都不顯示

問題&#xff1a;“執行 echo $USER 什么都不顯示”&#xff1f; 一、原因分析 環境變量 $USER 未正確設置 $USER 是系統自動定義的環境變量&#xff0c;通常用于表示當前登錄的用戶名。若該變量未設置或為空&#xff0c;執行 echo $USER 會無輸出。可能場景&#xff1a; 用戶通…

uni-app學習筆記五--vue3插值表達式的使用

vue3快速上手導航&#xff1a;簡介 | Vue.js 模板語法 插值表達式 最基本的數據綁定形式是文本插值&#xff0c;它使用的是“Mustache”語法 (即雙大括號)&#xff1a; <span>Message: {{ msg }}</span> 雙大括號標簽會被替換為相應組件實例中 msg 屬性的值。同…

【PSINS工具箱】基于工具箱的單獨GNSS導航、單獨INS導航、兩者結合組合導航,三種導航的對比程序。附完整的代碼

本文給出基于PSINS工具箱的單獨GNSS導航、單獨INS導航、兩者結合組合導航(153EKF)的程序。并提供三者的軌跡對比、誤差對比。 文章目錄 運行結果MATLAB代碼代碼的簡單介紹簡介2. 平均絕對誤差 (MAE)主要模塊運行結果 三軸軌跡圖: 各軸誤差曲線: 命令行窗口的結果輸出: …

C. scanf 函數基礎

scanf 函數 1. scanf 函數基礎1.1 函數原型與頭文件1.2 格式化輸入的基本概念2.1 常見格式說明符整數格式說明符浮點數格式說明符字符和字符串格式說明符其他格式說明符2.2 格式說明符的高級用法寬度修飾符精度修飾符跳過輸入字段寬度組合修飾符對齊修飾符實際應用示例3.2 精度…

spring cloud loadbalancer實現機房感知的負載均衡

1 概述 在同城多機房情景下&#xff0c;各個機房各自部署一套微服務集群&#xff0c;正常情況下微服務調用在本機房閉環。在如下某些災難情景&#xff0c;可以嘗試拉遠調用以最大程度維持業務連續性&#xff0c;這些情景例如&#xff1a; A機房多個服務器宕機。應用由于BUG發…

vue中,created和mounted兩個鉤子之間調用時差值受什么影響

在 Vue 中&#xff0c;created 和 mounted 是兩個生命周期鉤子&#xff0c;它們之間的調用時差主要受以下幾個因素影響&#xff1a; &#x1f7e2; 1. 模板復雜度與渲染耗時&#xff08;最主要因素&#xff09; mounted 的觸發時間是在組件的 DOM 被掛載之后&#xff08;也就是…

Linux篇 第2章Linux基礎指令

Linux篇 第2章Linux基礎指令 文章目錄 前言一、基礎的一些命令1.pwd2.mkdir3.ls4.cd5.clear 二、ls1.ls -l2.ls -a3.ls -l -a 三、touch四、 cd1.cd /2.cd ..3.cd ~4. cd - 五、tree1. Linux系統文件的結構2.絕對路徑和相對路徑 六、mkdir -p七、rmdir&#xff08;沒啥用&#…

Scrapyd 詳解:分布式爬蟲部署與管理利器

Scrapyd 是 Scrapy 官方提供的爬蟲部署與管理平臺&#xff0c;支持分布式爬蟲部署、定時任務調度、遠程管理爬蟲等功能。本文將深入講解 Scrapyd 的核心功能、安裝配置、爬蟲部署流程、API 接口使用&#xff0c;以及如何結合 Scrapy-Redis 實現分布式爬蟲管理。通過本文&#x…

國產免費工作流引擎star 6.5k,Warm-Flow升級1.7.2(新增案例和修復缺陷)

文章目錄 主要更新內容項目介紹功能思維導圖設計器流程圖演示地址官網Warm-Flow視頻 主要更新內容 [feat] 開啟流程實例&#xff0c;新增流程定義是否存在校驗[feat] 新增合同簽訂流程案例[feat] 新增企業采購流程案例[update] mybatis-plus邏輯刪除&#xff0c;刪除值和未刪除…

數據倉庫Hive

1.數據倉庫 1.1數據倉庫的概念 數據倉庫&#xff08;Data Warehouse&#xff09;是一個面向主題的、集成的、相對穩定的、反映歷史變化的數據集合&#xff0c;用于支持管理決策。 面向主題。操作型數據庫的數據組織面向事務處理任務&#xff0c;而數據倉庫中的數據按照一定的…

dify 連接不上ollama An error occurred during credentials validation:

三大報錯 An error occurred during credentials validation: HTTPConnectionPool(hosthost.docker.internal, port11434): Max retries exceeded with url: /api/chat (Caused by NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7f26fc3c00b0&…

uniapp 生成海報二維碼 (微信小程序)

先下載qrcodenpm install qrcode 調用 community_poster.vue <template><view class"poster-page"><uv-navbar title"物業推廣碼" placeholder autoBack></uv-navbar><view class"community-info"><text clas…

如何理解編程中的遞歸、迭代與回歸?

作為編程初學者&#xff0c;遞歸、迭代和回歸這三個概念常常讓人感到困惑。本文將通過生活化的比喻、Python代碼示例和直觀的對比&#xff0c;幫助你徹底理解這三個重要概念及其應用場景。 一、從生活比喻理解核心概念 1. 遞歸&#xff08;Recursion&#xff09;—— 俄羅斯套…