二分查找上下界問題的思考

背景

最近在做力扣hot100中的二分查找題目時,發現很多題目都用到了二分查找的變種問題,即二分查找上下界問題,例如以下題目:
35. 搜索插入位置
74. 搜索二維矩陣
34. 在排序數組中查找元素的第一個和最后一個位置

它們不同于查找等于target的位置,而是查找大于等于或者小于等于的位置,經過思考后總結出以下的思路,以35題“搜索插入位置”為例,這一題的插入位置即為第一個大于等于target的位置,以下是我的最終代碼:

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

推導

最初我看了他人的代碼之后感覺非常懵逼,為什么返回的是left呢?left為什么是第一個大于等于target的索引呢?思考了好一陣才想明白,我們來分析這里left和right的含義,重點在于它們的初始化和更新條件。

首先left初始化為0,0左側沒有任何元素,left左側的值小于等于target的性質成立。

之后left的每次更新,通過將left = mid + 1帶入到條件nums[mid] < target之中,我們可以得到left始終滿足nums[left-1] < target

與之類似的,right始終滿足nums[right+1] >= target的性質。

不斷更新直至left > right,更準確的說循環結束時left = right+1,考慮最后一次循環:

  1. 如果 left == right:
    • 如果 nums[mid] < target,那么 left = mid + 1 = right + 1,循環結束
    • 如果 nums[mid] >= target,那么 right = mid - 1 = left - 1,循環結束
  2. 如果 left + 1 == right,此時 mid = left:
    • 如果 nums[mid] < target,那么 left = mid + 1 = left + 1 = right,下一次循環會進入情況1
    • 如果 nums[mid] >= target,那么 right = mid - 1 = left - 1,此時 right < left,循環結束

因此,無論哪種情況,當循環結束時,都會有 left = right + 1。

在left和right都在數組索引(0, nums.size()-1)的范圍內的情況下,將left = right+1帶入left和right的性質得到nums[right] < targetnums[left] >= target

因此nums[left-1] < target <= nums[left]nums[right] < target <= nums[right+1],理解為left是第一個大于等于target的索引位置, right是第一個小于target的索引位置。

示例

以下圖為例:

輸入: nums = [1,3,5,6], target = 5

首先初始化left和right分別為0和3,然后計算得到mid等于1,由于索引1的值(3)小于target(5)。

因此left移動到mid+1(也就是2)的位置,說明在2左側(紅色范圍,不包括2)的所有值都小于target的值(5)。接下來計算得到mid等于2,由于索引2的值(5)大于等于target(5)。

因此right移動到mid-1(也就是1)的位置,說明1右側(黃色范圍,不包括1)的所有值都大于等于target的值(5)。

總結

if(nums[mid] < target)left = mid + 1;
elseright = mid - 1;

因此當我們設置以上的條件時,最終left和right都在數組范圍內的情況下,left一定是第一個大于等于target的索引位置(因為nums[left-1] < target <= nums[left]),right一定是第一個小于target的索引位置(因為nums[right] < target <= nums[right+1])。

反之,如果我們設置以下的條件,最終left一定是第一個大于target的索引位置,right一定是第一個小于等于target的索引位置。

if(nums[mid] <= target)left = mid + 1;
elseright = mid - 1;

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

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

相關文章

android adjust 卸載與重裝監測

想要洞察應用內用戶的留存率,可以通過Adjust 的卸載與重裝進行監測 名詞解釋: 卸載:集成完成后,卸載應用,安裝狀態為:卸載 重裝:如果應用已經卸載,但一段時間后又進行安裝,則會被視為重裝。 ??????:adjust 文件中說到24 小時后,可以再 adjust 控制臺看安裝…

算法系列——有監督學習——4.支持向量機

一、概述 支持向量機&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一種應用范圍非常廣泛的算法&#xff0c;既可以用于分類&#xff0c;也可以用于回歸。 本文將介紹如何將線性支持向量機應用于二元分類問題&#xff0c;以間隔&#xff08;margin&#x…

【Mani_skill】success判斷的核心調用邏輯

1. 可視化調用流程&#xff08;from Deepseek-r1-Cursor&#xff09; [RL算法調用 env.step()]↓ 調用 env.get_info()↓ 調用 env.evaluate() → 返回包含 success 的字典↓ 將 success 存入 info 字典↓ 在 step() 中處理終止條件&#xff1a; terminated success | fail

【圖像處理基石】什么是HDR圖片?

1. 什么是HDR圖片&#xff1f; HDR&#xff08;高動態范圍圖像&#xff0c;High Dynamic Range&#xff09;是一種通過技術手段擴展照片明暗細節的成像方式。以下是關于HDR的詳細說明&#xff1a; 核心原理 動態范圍&#xff1a;指圖像中最亮和最暗區域之間的亮度差。人眼能…

嵌入式筆記 | 正點原子STM32F103ZET6 4 | 中斷補充

1. 外設引腳重映射 1.1 定義 在STM32中&#xff0c;每個外設的引腳都有默認的GPIO端口&#xff0c;但有些引腳可以通過重映射寄存器將功能映射到其他端口。這種機制稱為引腳重映射&#xff0c;主要用于解決引腳復用沖突或優化PCB布線。 1.2 重映射的類型 部分重映射&#x…

如何選擇合適的 AI 模型?(開源 vs 商業 API,應用場景分析)

1. 引言 在 AI 迅猛發展的今天&#xff0c;各類 AI 模型層出不窮&#xff0c;從開源模型&#xff08;如 DeepSeek、Llama、Qwen&#xff09;到商業 API&#xff08;如 OpenAI 的 ChatGPT、Anthropic 的 Claude、Google Gemini&#xff09;&#xff0c;每種方案都有其優勢與適用…

攻克 3D 模型網站建設難題,看迪威系統優勢

在當今數字化時代&#xff0c;3D 模型廣泛應用于建筑設計、游戲開發、工業制造、文化創意等諸多領域。擁有一個功能強大的 3D 模型網站&#xff0c;對于企業展示產品、設計師分享作品、教育機構開展教學等都具有重要意義。然而&#xff0c;構建這樣一個網站卻并非易事&#xff…

使用uniapp的vite版本進行微信小程序開發,在項目中使用mqtt連接、訂閱、發布信息

1、保證在微信公眾平臺配置socket合法域名 2、項目中使用mqtt 建議在package.json中配置"mqtt": “4.1.0”&#xff0c;使用這個版本的依賴 頁面中引入mqtt并配置連接 // ts-ignoreimport * as mqtt from mqtt/dist/mqtt.js; //要使用這里面的const state reacti…

【FAQ】HarmonyOS SDK 閉源開放能力 —Map Kit(6)

1.問題描述&#xff1a; 使用華為內置的MapComponent&#xff0c; 發現顯示不出來。查看日志&#xff0c; MapRender底層有報錯。 解決方案&#xff1a; 麻煩按以下步驟檢查下地圖服務&#xff0c;特別是簽名證書指紋那部分。 1.一般沒有展示地圖&#xff0c;可能和沒有配置…

現代復古像素風品牌海報游戲排版設計裝飾英文字體 Psygen — Modern Pixel Font

Psygen 是一種像素化等寬字體&#xff0c;具有強烈的復古未來主義和網絡風格美學。塊狀的、基于網格的字體采用了早期的計算機界面、街機游戲排版和 ASCII 藝術。 該字體支持拉丁文、西里爾文和希臘文腳本&#xff0c;使其適用于多語言設計。擴展的字符集還具有唯一的符號和方…

小科普《DNS服務器》

DNS服務器詳解 1. 定義與核心作用 DNS&#xff08;域名系統&#xff09;服務器是互聯網的核心基礎設施&#xff0c;負責將人類可讀的域名&#xff08;如www.example.com&#xff09;轉換為機器可識別的IP地址&#xff08;如192.0.2.1&#xff09;&#xff0c;從而實現設備間的…

lunar是一款無第三方依賴的公歷 python調用

lunar是一款無第三方依賴的公歷(陽歷)、農歷(陰歷、老黃歷)、佛歷和道歷工具&#xff0c;支持星座、儒略日、干支、生肖、節氣、節日、彭祖百忌、吉神(喜神/福神/財神/陽貴神/陰貴神)方位、胎神方位、沖煞、納音、星宿、八字、五行、十神、建除十二值星、青龍名堂等十二神、黃道…

力扣hot100——三數之和(雙指針)

題目&#xff1a;三數之和 排序 雙指針 本題的難點在于如何去除重復解。 算法流程&#xff1a; 1、特判&#xff0c;對于數組長度 n&#xff0c;如果數組為 null 或者數組長度小于 3&#xff0c;返回 []。 2、對數組進行排序。 3、遍歷排序后數組&#xff1a; &#xff08…

操作系統為ubantu的服務器上部署nginx軟件基礎步驟總結

今天在這里&#xff0c;我們總結一下ubantu的服務器上部署nginx軟件&#xff0c;請按照以下步驟進行安裝&#xff1a; 1、更新包列表&#xff1a; 首先更新你系統中的可用軟件包列表&#xff0c;以確保你可以安裝最新版本。 sudo apt update2、 Ubuntu上更新已安裝軟件包&…

記錄一次,rabbitmq開啟stomp插件之后,還是連不上15674端口的問題

原因是裝在docker 里面的rabbitmq 沒有映射15674端口&#xff0c;需重新刪除容器之后重新運行 docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -p 15674:15674 -p 1883:1883 -p 15675:15675 rabbitmq:版本號 進入docker容器開啟插件 docker exec -it rabbitm…

MATLAB 控制系統設計與仿真 - 27

狀態空間的標準型 傳遞函數和狀態空間可以相互轉換&#xff0c;接下來會舉例如何有傳遞函數轉成狀態空間標準型。 對角標準型 當 G(s)可以寫成&#xff1a; 即&#xff1a; 根據上圖可知&#xff1a; 約當標準型 當 G(s)可以寫成&#xff1a; 即&#xff1a; 根據上圖…

1.FastAPI簡介與安裝

文章目錄 為什么選擇FastAPI&#xff1f;FastAPI支持的功能FastAPI的安裝第一個FastAPI應用運行應用 為什么選擇FastAPI&#xff1f; python web開發: Django: 適合大型復雜項目&#xff1b;Flask&#xff1a;適合靈活開發&#xff0c;搭建小型項目&#xff1b;FastAPI: 兼具開…

【MyDB】一個仿照MySQL的輪子項目系列文章匯總

迄今所有系列文章內容如下&#xff1a; 代碼位于xianghua-2/MYDB: 一個仿MySQL的簡易數據庫 1 項目環境配置以及整體項目結構 【MyDB】1-MyDB環境配置及項目結構-CSDN博客 2 TransactionManager事務管理模塊 【MyDB】2-TransactionManager 事務管理-CSDN博客 3 DataManage…

2025年汽車加氣站操作工考試精選題庫

汽車加氣站操作工題庫中題目及答案&#xff1a; 單項選擇題 1、按壓力容器的設計壓力分為&#xff08; &#xff09;個壓力等級。 A. 3 B. 4 C. 5 答案&#xff1a;B 2、緩沖罐的安裝位置在天然氣壓縮機&#xff08; &#xff09;。 A. 前 B. 后 C. 中間 答案&#…

【Unity Bug 隨記】使用Rider debug功能時Unity Reload Domain卡死問題

使用Rider debug功能時Unity Reload Domain卡死 檢查是否使用unity version control版本控制系統&#xff08;VCS&#xff09;&#xff0c;使用的話刪除這個包&#xff0c;再嘗試&#xff0c;如果能正常斷點調試&#xff0c;說明確實是VCS的問題。 我和幾個網友都是這個原因…