算法:二分查找

1.二分查找

704. 二分查找 - 力扣(LeetCode)

?二分查找算法要確定“二段性”,時間復雜度為O(lonN)。為了防止數據溢出,所以求mid時要用防溢出的方式。

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

樸素二分模版

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

2.在排序數組中查找元素的第一個和最后一個位置

34. 在排序數組中查找元素的第一個和最后一個位置 - 力扣(LeetCode)

用二分查找解決,要查找一個區間要找去左端點和右端點。

1. 查找區間的左端點

細節處理:

????????1. 循環條件 left < right 而不是left <= right?,因為left == right 的時候就是最終結果,無需判斷。如果判斷了就會死循環(當left和right構成的區間中存在結果,并且 nums[mid] >= t時,此時mid也等于left和right,進行上述操作的時候會導致right = mid一直在原地,所以導致死循環)。

????????2. 求中點的操作

left + (right - left)/ 2 要向下取整,當剩兩個點讓mid的指針指向left。

2.查找區間右端點

與查找區間左端點的方法類似,只是處理條件不同。

1.當nums[mid] <= target 時left == mid。

2.當nums[mid] > target 時right == mid - 1。

循環條件:left < right 和上述原因一致。

求中點的方式 left + (right - left + 1) / 2 要向上取整,當剩兩個點讓mid的指針指向right。

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {if(nums.size() == 0)return {-1, -1};int left = 0, right = nums.size() - 1;int begin = 0;while(left < right)//確定區間的左端點{int mid = left + (right - left) / 2;//防溢出寫法if(nums[mid] < target)left = mid + 1;elseright = mid;}//判斷是否有結果if(nums[left] != target)return {-1,-1};elsebegin = left;left = 0, right = nums.size() - 1;while(left < right)//確定區間的右端點{int mid = left + (right - left + 1) / 2;if(nums[mid] <= target)left = mid;else right = mid - 1;}//如果存在左端點,那么右端點也一定存在,所以不用判斷了,直接返回return {begin, right};}
};

總結二分模版

        while(left < right){int mid = left + (right - left) / 2;if(......)left = mid + 1;elseright = mid;}while(left < right)//確定區間的右端點{int mid = left + (right - left + 1) / 2;if(......)left = mid;else right = mid - 1;}

3. 搜索插入位置

35. 搜索插入位置 - 力扣(LeetCode)

?思路:二分查找,用左端點的模版,直接找到查找加返回要插入位置的值。如果未找到target,則檢查target是否大于nums[right]:如果是,插入位置為right + 1;否則,插入位置為right(即第一個大于等于target的位置)。

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

4. x的平方根

69. x 的平方根 - 力扣(LeetCode)

直接將1 ~ x作為查找區間,找小于等于mid*mid的x的值

class Solution {
public:int mySqrt(int x) {if(x < 1) return 0;long long left = 0, right = x;while(left < right){long long mid = left + (right - left + 1) / 2;if(mid * mid <= x)left = mid;elseright = mid - 1;}return left;}
};

5. 山脈數組的峰頂索引

852. 山脈數組的峰頂索引 - 力扣(LeetCode)

?運用二分查找算法,因為在山脈數組中,在前一段山脈arr[mid] > arr[mid - 1],在后一段山脈arr[mid] < arr[mid - 1];根據這個二段性,使用二分查找。

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

6. 尋找峰值

162. 尋找峰值 - 力扣(LeetCode)

運用二分查找算法:對于區間中nums[i] 和 nums[i + 1],如果nums[i] < nums[i + 1],那么這段區間程上升趨勢,因為nums[-1]和nums[n] =?-\infty,所以在后一段區間內一定有峰值,讓left = mid + 1.

如果nums[i] > nums[i + 1],程下降趨勢,在前一段區間內一定有峰值,讓right = mid。

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

7.尋找旋轉排序數組中的最小值

153. 尋找旋轉排序數組中的最小值 - 力扣(LeetCode)

?思路:使用二分查找,因為這個數組是有二段性的(要找的值為第二段的第一個元素),將這個數組分為兩段第一段的值一定比第二段的值大,所以根據nums[mid]和nums[n - 1]的關系作為比較。nums[mid]>nums[n - 1],說明在mid第一段,所以要讓left = mid + 1;nums[mid] <= nums[n - 1]時,說明mid在第二段上,要讓right = mid。

第二種方法是一nums[0]作為比較值,只是這種有特殊情況,全是升序的時候會導致mid一直向后走,所以找特殊判斷一下升序的情況。

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

8.點名

LCR 173. 點名 - 力扣(LeetCode)

?1.哈希表;2.直接遍歷找結構;3.位運算;4.求和公式。這些方法的時間復雜度都是O(N)。

方法5:二分查找:這個數組有二段性,分成兩段判斷對應的值是否相等,還需要處理一下全升序的情況

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

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

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

相關文章

day62—DFS—太平洋大西洋水流問題(LeetCode-417)

題目描述 有一個 m n 的矩形島嶼&#xff0c;與 太平洋 和 大西洋 相鄰。 “太平洋” 處于大陸的左邊界和上邊界&#xff0c;而 “大西洋” 處于大陸的右邊界和下邊界。 這個島被分割成一個由若干方形單元格組成的網格。給定一個 m x n 的整數矩陣 heights &#xff0c; hei…

Langchaine4j 流式輸出 (6)

Langchaine4j 流式輸出 大模型的流式輸出是指大模型在生成文本或其他類型的數據時&#xff0c;不是等到整個生成過程完成后再一次性 返回所有內容&#xff0c;而是生成一部分就立即發送一部分給用戶或下游系統&#xff0c;以逐步、逐塊的方式返回結果。 這樣&#xff0c;用戶…

自動駕駛與智能交通:構建未來出行的智能引擎

隨著人工智能、物聯網、5G和大數據等前沿技術的發展&#xff0c;自動駕駛汽車和智能交通系統正以前所未有的速度改變人類的出行方式。這一變革不僅是技術的融合創新&#xff0c;更是推動城市可持續發展的關鍵支撐。 一、自動駕駛與智能交通的定義 1. 自動駕駛&#xff08;Auto…

數據基座覺醒!大數據+AI如何重構企業智能決策金字塔(下)

1. 數據架構的量子躍遷 1.1 從線性堆疊到立體網絡 傳統六層架構正在經歷基因重組。某智能家居企業將數據流轉路徑重構為三維拓撲網絡后&#xff0c;新品研發周期從18個月壓縮至9個月。這個改造的核心在于打破數據層間的物理隔離&#xff0c;讓原始數據流能直接觸達決策中樞。…

Linux 腳本文件編輯(vim)

1. 用戶級配置文件&#xff08;~/.bashrc&#xff09; vim ~/.bashrc # 編輯 source ~/.bashrc # 讓編輯生效 ~/.bashrc 文件是 Bash Shell 的配置文件&#xff0c;用于定義用戶登錄時的環境變量、別名、函數等設置。當你修改了 ~/.bashrc 文件后&#xff0c;通常需要重新…

【Pytorch學習筆記】模型模塊06——hook函數

hook函數 什么是hook函數 hook函數相當于插件&#xff0c;可以實現一些額外的功能&#xff0c;而又不改變主體代碼。就像是把額外的功能掛在主體代碼上&#xff0c;所有叫hook&#xff08;鉤子&#xff09;。下面介紹Pytorch中的幾種主要hook函數。 torch.Tensor.register_h…

SQL進階之旅 Day 11:復雜JOIN查詢優化

【SQL進階之旅 Day 11】復雜JOIN查詢優化 在數據處理日益復雜的今天&#xff0c;JOIN操作作為SQL中最強大的功能之一&#xff0c;常常成為系統性能瓶頸。今天我們進入"SQL進階之旅"系列的第11天&#xff0c;將深入探討復雜JOIN查詢的優化策略。通過本文學習&#xf…

Spring AI 之檢索增強生成(Retrieval Augmented Generation)

檢索增強生成&#xff08;RAG&#xff09;是一種技術&#xff0c;有助于克服大型語言模型在處理長篇內容、事實準確性和上下文感知方面的局限性。 Spring AI 通過提供模塊化架構來支持 RAG&#xff0c;該架構允許自行構建自定義的 RAG 流程&#xff0c;或者使用 Advisor API 提…

前端開源JavaScrip庫

以下內容仍在持續完善中&#xff0c;如有遺漏或需要補充之處&#xff0c;歡迎在評論區指出。感謝支持&#xff0c;如果覺得有幫助&#xff0c;歡迎點贊鼓勵。感謝支持 JavaScript 框架Vue.jsVue.js - 漸進式 JavaScript 框架 | Vue.jsReactReactAngularHome ? AngularjQueryj…

什么是 CPU 緩存模型?

導語&#xff1a; CPU 緩存模型是后端性能調優、并發編程乃至分布式系統設計中一個繞不開的核心概念。它不僅關系到指令執行效率&#xff0c;還影響鎖機制、內存可見性等多個面試高頻點。本文將以資深面試官視角&#xff0c;詳解緩存模型的原理、常見面試題及實戰落地&#xff…

海外tk抓包簡單暴力方式

將地址替換下面代碼就可以 function hook_dlopen(module_name, fun) {var android_dlopen_ext Module.findExportByName(null, "android_dlopen_ext");if (android_dlopen_ext) {Interceptor.attach(android_dlopen_ext, {onEnter: function (args) {var pathptr …

多模態大語言模型arxiv論文略讀(103)

Are Bigger Encoders Always Better in Vision Large Models? ?? 論文標題&#xff1a;Are Bigger Encoders Always Better in Vision Large Models? ?? 論文作者&#xff1a;Bozhou Li, Hao Liang, Zimo Meng, Wentao Zhang ?? 研究機構: 北京大學 ?? 問題背景&…

代碼隨想錄算法訓練營 Day61 圖論ⅩⅠ Floyd A※ 最短路徑算法

圖論 題目 97. 小明逛公園 本題是經典的多源最短路問題。 在這之前我們講解過&#xff0c;dijkstra樸素版、dijkstra堆優化、Bellman算法、Bellman隊列優化&#xff08;SPFA&#xff09; 都是單源最短路&#xff0c;即只能有一個起點。 而本題是多源最短路&#xff0c;即求多…

【機器學習】集成學習與梯度提升決策樹

目錄 一、引言 二、自舉聚合與隨機森林 三、集成學習器 四、提升算法 五、Python代碼實現集成學習與梯度提升決策樹的實驗 六、總結 一、引言 在機器學習的廣闊領域中,集成學習(Ensemble Learning)猶如一座閃耀的明星,它通過組合多個基本學習器的力量,創造出…

yarn、pnpm、npm

非常好&#xff0c;這樣從“問題驅動 → 工具誕生 → 優化演進”的角度來講&#xff0c;更清晰易懂。下面我按時間線和動機&#xff0c;把 npm → yarn → pnpm 的演變脈絡講清楚。 &#x1f9e9; 一、npm 為什么一開始不夠好&#xff1f; 早期&#xff08;npm v4 及之前&…

如何用AI寫作?

過去半年&#xff0c;我如何用AI高效寫作&#xff0c;節省數倍時間 過去六個月&#xff0c;我幾乎所有文章都用AI輔助完成。我的朋友——大多是文字工作者&#xff0c;對語言極為敏感——都說看不出我的文章是AI寫的還是親手創作的。 我的AI寫作靈感部分來自丘吉爾。這位英國…

什么是trace,分布式鏈路追蹤(Distributed Tracing)

在你提到的 “個人免費版” 套餐中&#xff0c;“Trace 上報量&#xff1a;5 萬條 / 月&#xff0c;存儲 3 天” 里的 Trace 仍然是指 分布式鏈路追蹤記錄&#xff0c;但需要結合具體產品的場景來理解其含義和限制。以下是更貼近個人用戶使用場景的解釋&#xff1a; 一、這里的…

[免費]微信小程序網上花店系統(SpringBoot后端+Vue管理端)【論文+源碼+SQL腳本】

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;看到一個不錯的微信小程序網上花店系統(SpringBoot后端Vue管理端)【論文源碼SQL腳本】&#xff0c;分享下哈。 項目視頻演示 【免費】微信小程序網上花店系統(SpringBoot后端Vue管理端) Java畢業設計_嗶哩嗶哩_bilibili 項…

PyTorch——DataLoader的使用

batch_size, drop_last 的用法 shuffle shuffleTrue 各批次訓練的圖像不一樣 shuffleFalse 在第156step順序一致

【Linux】基礎文件IO

&#x1f31f;&#x1f31f;作者主頁&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所屬專欄&#xff1a;Linux 前言 無論是日常使用還是系統管理&#xff0c;文件是Linux系統中最核心的概念之一。對于初學者來說&#xff0c;理解文件是如何被創建、讀取、寫入以及存儲…