二分搜索邊界問題

在使用二分搜索的時候,更新條件不總是相同,雖然說使用bS目的就是為了target,但也有如下幾種情況:

  1. 求第一個=target的索引

  2. 求第一個>target的索引

  3. 求第一個>=target的索引

  4. 求最后一個=target的索引

  5. 求最后一個<target的索引

  6. 求最后一個<=target的索引

從這六種情況來看,其實可以分成兩種搜索:左邊界搜索->最小滿足條件的索引右邊界搜索->最大滿足條件的索引。這么說可能有點抽象,看1-3種情況:都是求第一個符合查詢條件的索引,也就是遇到符合條件的索引就返回,即最小索引;4-6種情況:求最后一個符合查詢條件的索引,即最大的符合條件的索引即最大索引。

定義查詢條件為check(nums[m])接下來分兩種情況討論:

  • 左邊界問題:

    • 先給結論,左邊界判斷時,要一直收縮右側以達到不斷判斷左側數據是否符合查詢條件的目的,因而當符合check條件的操作與nums[m]>t時操作相同,收縮r=m。之所以是r=m而不是r=m-1,是因為符合check條件時,此r也可能是解,所以不能跳過這個r。

    • 左邊界通用代碼

      int l=0,r=n-1;
      while(l<r){int m = l+(r-l)/2;if(check(m)) r = m;else l = m+1;
      }
      return l;
    • 求第一個=target的索引:

      • check為 nums[m] == target與nums[m]>target合并

      • while(l<r){int m = l+(r-l)/2;if(nums[m] >= target) r = m;else l = m+1;
        }
        return (nums[l] == target) ? l : -1;
    • 求第一個>target的索引:

      • check為nums[m] > target

      • while(l<r){int m = l+(r-l)/2;if(nums[m] > target) r = m;else l = m+1;
        }
        return l;
    • 求第一個>=target的索引:

      • check為nums[m]>=target

      • while(l<r){int m = l+(r-l)/2;if(nums[m] >= target) r = m;else l = m+1;
        }
        return l;
  • 右邊界問題

    • 右邊界問題要求的是最大的滿足條件的索引,因而要收縮左側以達到一直判斷右側數據是否能夠符合查詢條件的目的。因而當符合check條件的操作與nums[m]<t時操作相同,收縮l=m。之所以是l=m而不是l=m+1,是因為符合check條件時,此l也可能是解,所以不能跳過這個l。

    • 右邊界涉及到一個m向上取整的問題,也就是m每次計算m = (l+r+1)/2;原因是,右邊界搜索會令l=m,若m向下取整,接近臨界條件時有可能導致m=(l+r)/2=l的情況,那么再次遇上收縮,l=m。如此循環導致搜索無法跳出。

    • 右邊界搜索通用代碼:

      int l=0,r=n-1;
      while(l<r){int m = (r+l+1)/2;if(check(m)) l = m;else r=m-1;
      }
    • 求最后一個=target的索引

      • check為 nums[m] == target歸并到nums[m] < target中

      • while(l<r){int m = (l+r+1)/2;if(nums[m] <= target) l = m;else r = m-1;
        }
        return (nums[l] == target) ? l : -1;
    • 求最后一個<target的索引

      • check為nums[m] < target

      • while(l<r){int m = (l+r+1)/2;if(nums[m] < target) l = m;else r = m-1;
        }
        return l;
    • 求最后一個<=target的索引

      • check為nums[m]<=target

      • while(l<r){int m = (l+r+1)/2;if(nums[m] <= target) l = m;else r = m-1;
        }
        return l;
類型常見題號
第一個 == targetLC 34
最后一個 == targetLC 34
第一個 ≥ targetLC 35, LC 300, LC 378
最后一個 ≤ targetLC 34, LC 2080
第一個 > targetLC 875, LC 410, LC 1011
最后一個 < targetLC 74, LC 2300

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

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

相關文章

【springboot+vue3】博客論壇管理系統(源碼+文檔+調試+基礎修改+答疑)

目錄 一、整體目錄&#xff1a; 項目包含源碼、調試、修改教程、調試教程、講解視頻、開發文檔&#xff08;項目摘要、前言、技術介紹、可行性分析、流程圖、結構圖、ER屬性圖、數據庫表結構信息、功能介紹、測試致謝等約1萬字&#xff09; 二、運行截圖 三、代碼部分&…

20250907_梳理異地備份每日自動巡檢Python腳本邏輯流程+安裝Python+PyCharm+配置自動運行

一、邏輯流程(autocheckbackup.py在做什么) 1.連接Linux服務器 用 paramiko 登錄你配置的 Linux 服務器(10.1.3.15, 10.1.3.26),進入指定目錄(如 /home, /backup/mes),遞歸列出文件。 采集到的信息:服務器IP、目錄、數據庫名稱、文件名、大小、修改時間。 2.連接Wind…

terraform-state詳解

一、Treeaform-state的作用 Terraform-state是指Terroform的狀態&#xff0c;是terraform不可缺少的生命周期元素。本質上來講&#xff0c;terraform狀態是你的基礎設施配置的元數據存儲庫&#xff0c;terraform會把它管理的資源狀態保存在一個狀態文件里。 默認情況下&#xf…

四、kubernetes 1.29 之 Pod 生命周期

一、概述當容器與 pause 容器共享網絡&#xff08;Network&#xff09;、IPC&#xff08;進程間通信&#xff09;和 PID&#xff08;進程命名空間&#xff09;后&#xff0c;二者形成了一種緊密的 "共享命名空間" 關系&#xff0c;共同構成了 Kubernetes 中 "Po…

AI與環保:禮貌用語背后的能源挑戰與解決方案

程序員的技術管理推薦閱讀 窄化效應&#xff1a;程序員與管理者的隱形情緒陷阱 從“激勵”到“保健”&#xff1a;80后與90后程序員&#xff0c;到底想要什么&#xff1f; 從“激勵”到“保健”&#xff1a;80后與90后程序員&#xff0c;到底想要什么&#xff1f; 場景引入&…

OpenCV C++ 特征提取:從角點檢測到對象識別

特征提取是計算機視覺的核心技術,通過識別圖像中具有代表性的關鍵點及其描述信息,實現圖像匹配、對象識別、姿態估計等高級任務。本章將系統講解從基礎的圖像金字塔、角點檢測,到復雜的 ORB 和 SIFT 特征提取與匹配,最終實現基于特征的對象檢測完整流程。 一、圖像金字塔 …

Codeforces Round 1049 (Div. 2) D題題解記錄

大致題意&#xff1a;給定nnn個區間(li,ri)(l_i,r_i)(li?,ri?)。每次選取兩個尚未被標記的區間(l1,r1)(l_1,r_1)(l1?,r1?)與(l2,r2)(l_2,r_2)(l2?,r2?)&#xff0c;使得他們均被標記&#xff0c;同時可以任選x∈[l1,r1]&#xff0c;y∈[l2,r2]x\in[l_1,r_1]&#xff0c;y…

《WINDOWS 環境下32位匯編語言程序設計》第15章 注冊表和INI文件

15.1 注冊表和INI文件簡介在一個操作系統中&#xff0c;無論是操作系統本身還是運行于其中的大部分應用程序&#xff0c;都需要使用某種方式保存配置信息。在DOS系統中&#xff0c;配置信息往往是軟件的開發者根據自己的喜好用各種途徑加以保存的&#xff0c;比如在磁盤上面寫一…

JDK 17、OpenJDK 17、Oracle JDK 17 的說明

Java生態系統的核心概念&#xff1a;簡單來說&#xff1a;JDK 17 是一個標準規范&#xff0c;定義了Java開發工具包第17個長期支持版應該包含什么功能。openjdk-17-jdk 是一個具體的實現&#xff0c;是遵循上述規范、由OpenJDK社區提供的開源軟件包。下面我們通過一個表格和詳細…

手寫MyBatis第58彈:如何優雅輸出可執行的SQL語句--深入理解MyBatis日志機制:

&#x1f942;(???)您的點贊&#x1f44d;?評論&#x1f4dd;?收藏?是作者創作的最大動力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;點贊&#x1f44d;收藏??留言&#x1f4dd;歡迎留言討論 &#x1f525;&#x1f525;&…

Spring Boot 監控實戰:集成 Prometheus 與 Grafana,打造全方位監控體系

前言 在當今微服務架構盛行的時代&#xff0c;應用程序的監控變得尤為重要。Spring Boot 作為廣泛使用的微服務框架&#xff0c;其監控需求也日益增加。Prometheus 和 Grafana 作為開源監控領域的佼佼者&#xff0c;為 Spring Boot 應用提供了強大的監控能力。本文將詳細介紹如…

JS中的多線程——Web Worker

眾所周知&#xff0c;JavaScript 是單線程運行的&#xff08;至于為什么是單線程可以看一下這篇文章——事件循環機制&#xff09;&#xff0c;當瀏覽器主線程被大量計算任務阻塞時&#xff0c;頁面就會出現明顯的卡頓現象。Web Worker 提供了在獨立線程中運行 JavaScript 的能…

【SQL注入】延時盲注

sleep(n)??: 核心延時函數。使數據庫程序暫停 n秒。??if(condition, true_expr, false_expr)??: 條件判斷函數。如果 condition為真&#xff0c;執行 true_expr&#xff0c;否則執行 false_expr。??用于將延時與判斷條件綁定??。??mid(a, b, c)??: 字符串截取函數…

IntelliJ IDEA 2025.1 Java Stream Debugger 快速使用指南

1. 功能概覽 Java Stream Debugger 提供 Trace Current Stream Chain 功能&#xff0c;用來在調試時分析和可視化 Stream 操作鏈。 主要用途&#xff1a; 在運行時查看流操作鏈的每一步輸出找出 map/filter 等操作的問題避免手動加 peek() 打印調試2. 使用入口 在 IDEA 2025.1 …

ARM-指令集全解析:從基礎到高階應用

一、ARM 指令集體系結構版本ARM 公司定義了多個指令集版本&#xff1a;ARMv1&#xff1a;原型機 ARM1&#xff0c;沒有用于商業產品。ARMv2&#xff1a;擴展 V1&#xff0c;包含 32 位乘法指令和協處理器指令。ARMv3&#xff1a;第一個微處理器 ARM6 核心&#xff0c;支持 Cach…

第3講 機器學習入門指南

近年來&#xff0c;隨著企業和個人生成的數據量呈指數級增長&#xff0c;機器學習已成為日益重要的技術領域。從自動駕駛汽車到流媒體平臺的個性化推薦&#xff0c;機器學習算法已廣泛應用于各個場景。讓我們深入解析機器學習的核心要義。3.1 機器學習定義機器學習是人工智能的…

深入理解跳表:多層索引加速查找的經典實現

跳表&#xff08;Skip List&#xff09;是一種多層有序鏈表結構&#xff0c;通過引入多級索引加速查找&#xff0c;其核心設計類似于“立體高速公路系統”&#xff0c;底層是原始鏈表&#xff0c;上面有各種高度的"高架橋"。 高層道路跨度大&#xff0c;連接遠方節點…

Flutter 視頻播放器——flick_video_player 介紹與使用

在移動端應用中&#xff0c;視頻播放是一個常見的功能場景&#xff0c;例如短視頻、直播、課程、廣告展示等。 Flutter 本身并沒有直接提供視頻播放器組件&#xff0c;而是依賴第三方庫來實現。 今天要介紹的庫是 flick_video_player&#xff0c;它基于 video_player 封裝&…

編寫cmakelists文件常用語句

cmake_minimum_required (VERSION 3.10) 指定最小版本project(XXXX) 指定項目名字 ---------------set(MAIN_EXEC_NAME dwarf_parser) 定義變量${ MAIN_EXEC_NAME } 變量取值set(CMAKE_CXX_STANDARD 14) 指定c14標準&#xff0c;還有11、17、20等標準…

麒麟桌面系統找不到mbr啟動,并重新安裝grub

根據你提供的情況,“麒麟桌面系統找不到MBR啟動”,這通常是由于GRUB引導損壞、MBR記錄丟失或分區表異常導致的。你可以按照以下步驟重新安裝GRUB并修復MBR啟動: ? 步驟一:準備工具 使用銀河麒麟LiveCD或U盤啟動盤(可用Ventoy制作); 啟動電腦,選擇從U盤或光盤進入Live環…