hot100 -- 二分查找

目錄

前言

🎂搜索插入位置

🌼搜索二維矩陣

🌼排序數組元素第一和最后一個位置

🌼旋轉排序數組

💪旋轉排序數組中的最小值

💪兩個正序數組的中位數


前言

二分算法學習_時間超限ac:0%-CSDN博客

🎂搜索插入位置

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

直接套博客里的萬能模板不太行,萬能模板只能處理下取整死循環的問題,但是本題:

目標值 target 不一定在數組里

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l <= r) {int m = (l + r) >> 1;if (target > nums[m])l = m + 1;else if (target < nums[m])r = m - 1;else {l = m;break;}}// 因為 l<=r 退出循環后, r 必然位于插入位置return l;}
};

🌼搜索二維矩陣

74. 搜索二維矩陣 - 力扣(LeetCode)

1)別混淆 mid 和 m,此處 m 是 m 行,mid 才是中間值

2)對第 3 種情況,target == matrix[][],進行處理

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size(), n = matrix[0].size();int l = 0, r = m*n - 1; // 二維轉一維while (l < r) {int mid = (l + r + 1) >> 1;if (target > matrix[mid/n][mid%n]) // 一維轉二維l = mid;else if (target < matrix[mid/n][mid%n])r = mid - 1;else {l = mid;break;}}return matrix[l/n][l%n] == target;}
};

🌼排序數組元素第一和最后一個位置

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

1)利用 while (l <= r) { ... l = m + 1 ... r = m - 1?};? 左閉右閉區間

退出循環時,l 的位置就是 >= target 的最小的數

r == l - 1

2)只需求出第一個位置,即可取巧得到最后一個位置,現在有二分函數 lowerbound(nums, target) 得到第一個位置,最后一個位置即 lowerbound(nums, target + 1) - 1

3)奇數個元素,m = (l + r) / 2,取到中間的元素;偶數個元素,因為整數默認下取整,會取中間兩個元素左邊那個

坑:

1)不要用 >> 1,要用 / 2,不知道力扣是不是不支持位移運算符(>> 1 會超出時間限制)?

2)如果想要從 r = m - 1 開始,那么最后應該 return r;? ?r 此時位于最后一個位置(詳情看代碼 2)(用例1模擬一下)

代碼 1

class Solution {
public:// >= target 的最小的數的位置int lowerbound(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l <= r) {int m = l + (r - l) / 2;if (target > nums[m])l = m + 1;elser = m - 1;}return l; // 第一個位置}vector<int> searchRange(vector<int>& nums, int target) {int start = lowerbound(nums, target);if (start >= nums.size() || nums[start] != target)return {-1, -1};int end = lowerbound(nums, target + 1) - 1;return {start, end};}
};

代碼 2

class Solution {
public:// >= target 的最小的數的位置int lowerbound(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l <= r) {int m = l + (r - l) / 2;if (target < nums[m])r = m - 1;elsel = m + 1;}return r; // 最后一個位置}vector<int> searchRange(vector<int>& nums, int target) {int end = lowerbound(nums, target);if (end < 0 || nums[end] != target)return {-1, -1};int start = lowerbound(nums, target - 1) + 1;return {start, end};}
};

🌼旋轉排序數組

33. 搜索旋轉排序數組 - 力扣(LeetCode)

1)二分時,套 while (l <= r) 的模板,mid 位于中間 OR 中間偏左位置

此時,[l, mid] OR [mid + 1, r],至少一個區間是有序的,所以對左右區間的有序分類討論

class Solution {
public:int search(vector<int>& nums, int target) {int n = nums.size();int l = 0, r = n - 1;// 二分找到 k 的位置while (l <= r) {int mid = (l + r) / 2;// target 位于 midif (nums[mid] == target)return mid;// 左邊有序else if (nums[l] <= nums[mid]) {// target 位于左邊(不包括 mid)if (nums[l] <= target && target < nums[mid]) r = mid - 1;else l = mid + 1;}// 右邊有序else {// target 位于右邊(不包括 mid)if (nums[mid] < target && target <= nums[r])l = mid + 1;elser = mid - 1;}}return -1; // 未找到}
};

💪旋轉排序數組中的最小值

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

上一題是找目標值,本題是找最小值(都滿足部分有序)

本題每次旋轉,將最后一個值提取到最前面

可以畫幾個例子多驗證一下:2 0 1,1 2 0,3 4 5 2,5 2 3 4

最小值處于斷崖的第一個位置,顯而易見,肯定位于無序一邊

所以每次壓縮有序部分,到無序部分找,注意結合例子處理邊界

class Solution {
public:int findMin(vector<int>& nums) {int n = nums.size();int l = 0, r = n - 1;while (l <= r) { // l < r 也行// 單調升序if (nums[l] <= nums[r]) // 用 = 防止單個元素時死循環return nums[l];int m = (l + r) / 2;// 左邊有序if (nums[m] >= nums[l]) // 用 = 防止 r 跳過最小值l = m + 1; // 去右邊找elser = m; // 不用 m-1 防止跳過最小值}return nums[l];}
};

💪兩個正序數組的中位數

4. 尋找兩個正序數組的中位數 - 力扣(LeetCode)

結合這篇博客理解一下,用刪除(淘汰)的思路
尋找兩個正序數組的中位數(292) | 小浩算法 (geekxh.com)

輔助數組 findKth(nums1, i, nums2, j, k),i, j 是兩個數組起始索引,第 k 大元素

如果第一個數組起始位置 i + 2/k - 1 的值 < 第二個數組起始位置 j + 2/k - 1 的值

那么就淘汰掉第一個數組前 2/k 個元素,反之淘汰另一個數組前 2/k 個元素

直到 k == 1,此時比較兩個數組起始第 1 個元素大小即可

或者一個數組為空(即 i >= nums1.size() 或 j >= nums2.size())

時間 O(log( max(m, n) ))

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n = nums1.size(), m = nums2.size();int left = (n + m + 1) / 2, right = (n + m + 2) / 2; // 中間值索引 left 和 rightreturn (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;}// nums1 起始索引 i, nums2 起始索引 j, 返回合并數組 第 k 個元素(1開始算)int findKth(vector<int>& nums1, int i, vector<int>& nums2, int j, int k) {if (i >= nums1.size()) // nums1 空數組return nums2[j + k - 1];if (j >= nums2.size()) // nums2 空數組return nums1[i + k - 1];if (k == 1)return min(nums1[i], nums2[j]); // 返回較小值// 2/k 位置的值// 如果一個數組 k/2 處超出范圍, 無法判斷中位數是否位于這個數組// 但是另一個數組前 k/2 個肯定沒有中位數// 取 MAX, 淘汰另一個數組前 k/2 個元素int mid1 = (i + k/2 - 1 < nums1.size()) ? nums1[i + k/2 - 1] : INT_MAX;int mid2 = (j + k/2 - 1 < nums2.size()) ? nums2[j + k/2 - 1] : INT_MAX;// 遞歸二分if (mid1 < mid2) // mid1 淘汰 k/2return findKth(nums1, i + k/2, nums2, j, k - k/2);else // mid2 淘汰 k/2return findKth(nums1, i, nums2, j + k/2, k - k/2);}
};

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

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

相關文章

2024年【起重機械指揮】考試及起重機械指揮新版試題

題庫來源&#xff1a;安全生產模擬考試一點通公眾號小程序 起重機械指揮考試考前必練&#xff01;安全生產模擬考試一點通每個月更新起重機械指揮新版試題題目及答案&#xff01;多做幾遍&#xff0c;其實通過起重機械指揮試題及解析很簡單。 1、【多選題】《中華人民共和國特…

【Androi】安卓發展歷程詳解

人不走空 &#x1f308;個人主頁&#xff1a;人不走空 &#x1f496;系列專欄&#xff1a;算法專題 ?詩詞歌賦&#xff1a;斯是陋室&#xff0c;惟吾德馨 目錄 &#x1f308;個人主頁&#xff1a;人不走空 &#x1f496;系列專欄&#xff1a;算法專題 ?詩詞歌…

git推送代碼到github拒絕推送的解決方案

這里描述一下本地推送的場景&#xff0c;首先我在碼云上建立了一個前端項目&#xff0c;進行了自己的個性化開發&#xff0c;后期在github上創建了一個一樣的項目倉庫存放代碼。使用webstorm進行代碼開發。在下面這個位置可以選擇推送的代碼位置。 選擇推送github倉庫之后&…

Python深度學習基于Tensorflow(16)基于Tensorflow的對話實例

文章目錄 基礎數據清洗數據生成詞匯表定義分詞器并制作數據集構建Transformer模型并訓練模型推理 Tensorflow 的核心就是注意力機制&#xff0c;在之前詳細的介紹過&#xff0c;具體可以看這個&#xff1a;Python深度學習基于Tensorflow&#xff08;9&#xff09;注意力機制_te…

在Java中為什么對a賦值為10,在進行a++時還是等于10呢

首先我們看這樣一組代碼 public class demo1 {public static void main(String[] args) {int a10;aa;System.out.println(a);} } 結果&#xff1a;10不是在第二步有a操作嗎&#xff1f;為什么還是10呢&#xff1f; a的執行步驟如下&#xff1a; 保存當前a的值&#xff08;即10…

websocket鏈接攜帶參數

前端創建鏈接時官方提供的構造函數 var aWebSocket new WebSocket(url, [protocols]); url&#xff1a;要連接的URL&#xff1b;這應該是WebSocket服務器將響應的URL。 protocols&#xff1a;可選&#xff1b;一個協議字符串或者一個包含協議字符串的數組。這些字符串用于指定…

智能語音電銷機器人可以做哪些事情?ai語音機器人系統

智能語音電銷機器人軟件的出現&#xff0c;給很多企業都帶來了福利&#xff0c;尤其是電銷企業&#xff0c;不僅工作效率提升了&#xff0c;成本降低了&#xff0c;還能實現智能化管理客戶的出現&#xff0c;給很多企業都帶來了福利&#xff0c;尤其是電銷企業&#xff0c;不僅…

python初學者筆記(八)——數字階乘

#python初學者筆記&#xff08;8&#xff09;——數字階乘 階乘是基斯頓卡曼于 1808 年發明的運算符號,是數學術語,一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積。 下面利用Python編寫數字階乘 ##1.方法一:利用函數的方法&#xff0c;求輸入值的階乘 #coding…

WebAPI 前端開發流程:深度解析與實踐探索

WebAPI 前端開發流程&#xff1a;深度解析與實踐探索 在前端開發的世界里&#xff0c;WebAPI扮演著至關重要的角色&#xff0c;它作為前端與后端溝通的橋梁&#xff0c;確保了數據的流暢傳輸與功能的完整實現。本文將詳細探討WebAPI前端開發流程&#xff0c;從四個方面、五個方…

什么情況下需要配戴助聽器

以下幾種情況需要考慮配戴助聽器&#xff1a; 1、聽力無波動3個月以上的感音神經性聽力障礙。如:先天性聽力障礙、老年性聽力障礙、噪聲性聽力障礙、突聾的穩定期等&#xff0c;均可選配合適的助聽器。 2、年齡方面。使用助聽器沒有嚴格的年齡限制&#xff0c;從出生數周的嬰…

深度學習Week16——數據增強

文章目錄 深度學習Week16——數據增強 一、前言 二、我的環境 三、前期工作 1、配置環境 2、導入數據 2.1 加載數據 2.2 配置數據集 2.3 數據可視化 四、數據增強 五、增強方式 1、將其嵌入model中 2、在Dataset數據集中進行數據增強 六、訓練模型 七、自定義增強函數 一、前言…

Geoserver源碼解讀一(環境搭建)

一、Github地址 https://github.com/geoserver/geoserver 1.1 克隆代碼 git clone https://github.com/geoserver/geoserver.git 1.2 選擇版本 版本選擇參考我的上一篇文章 Geoserver 以及 Geotools各版本和jdk版本對照表 此處我選擇的是兼容jdk8的最后一個版本 git che…

netty+springboot+vue聊天室(需要了解netty)

先看看這個使用websocket實現的聊天室&#xff0c;因為前端是使用websocket&#xff0c;和下面的demo的前端差不多就不解釋實現原理&#xff0c;所以建議還是看看(要是會websocket的大佬請忽略) springbootwebsocketvue聊天室 目錄 一、實現內容二、代碼實現1.后端2.前端源碼…

html+CSS+js部分基礎運用17

在圖書列表中&#xff0c;為書名“零基礎學JavaScript”和“HTML5CSS3精彩編程200例”添加顏色。&#xff08;請用class或style屬性實現&#xff09;&#xff0c;效果如下圖1所示&#xff1a; 圖1 圖書列表 Class和style的綜合應用。&#xff08;1&#xff09;應用class的對象、…

命令行打包最簡單的android項目從零開始到最終apk文件

準備好需要的工具 AndroidDevTools - Android開發工具 Android SDK下載 Android Studio下載 Gradle下載 SDK Tools下載 jdk的鏈接我就不發出來,自己選擇,我接下來用的是8版本的jdk和android10的sdk sdk的安裝和環境變量的配置 sdk tool壓縮包打開后是這樣子,打開sdk mana…

高防CDN是如何應對DDoS和CC攻擊的

高防CDN&#xff08;內容分發網絡&#xff09;主要通過分布式的網絡架構來幫助網站抵御DDoS&#xff08;分布式拒絕服務&#xff09;和CC&#xff08;挑戰碰撞&#xff09;攻擊。 下面是高防CDN如何應對這些攻擊的詳細描述&#xff1a; 1. DDoS攻擊防護 DDoS攻擊通過大量的惡…

SREC用什么軟件編程:全面解析與編程工具選擇

SREC用什么軟件編程&#xff1a;全面解析與編程工具選擇 在嵌入式系統開發中&#xff0c;SREC文件格式扮演著至關重要的角色&#xff0c;用于存儲和傳輸二進制數據。然而&#xff0c;對于許多初學者和開發者來說&#xff0c;如何選擇合適的軟件來編寫SREC文件卻是一個令人困惑…

STM32串口DMA 空閑中斷使用筆記

這里只記錄注意要點&#xff1a; 1&#xff0c;要開啟串口 全局中斷 和對應的接收DMA 中斷&#xff0c;兩個中斷必須同時開 2&#xff0c;裸機程序需要在主循環外調用一次 這個函數 HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx_buff, BUFF_SIZE); 3&#xff0c;要在串口中…

【動態規劃-BM71 最長上升子序列(一)】

題目 BM71 最長上升子序列(一) 分析 dp[i] 考慮到下標i&#xff0c;其組成的最長上升子序列長度 可以用動態規劃的原因&#xff1a; 到i的結果可以由到j &#xff08;j<i) 的結果推出&#xff0c;只需要判斷下標j對應的數字是否比下標i 對應的字母小即可 注意&#xf…

vs2013 - 打包

文章目錄 vs2013 - 打包概述installshield2013limitededitionMicrosoft Visual Studio 2013 Installer Projects選擇哪種來打包? 筆記VS2013打包和VS2019打包的區別打包工程選擇view打包工程中單擊工程名稱節點&#xff0c;就可以在屬性框中看到要改的屬性(e.g. 默認是x86, 要…