Leetcode百題斬-二分搜索

二分搜索也是一個很有趣的專題,被做過的題中,剛好一個Easy,一個Medium和一個Hard,剛好可以看看,二分搜索的三個難度等級都是啥樣的。

124. Binary Tree Maximum Path Sum[Hard](詳見二叉樹專題)

先來看Hard,一看不對勁,這一題和二分搜索不能說是毫無關系,只能說毫不相關,這就是個純純的二叉樹的題,趕緊從這個專題剔除,寫到二叉樹專題里了

Leetcode百題斬-二叉樹-最大路徑和-CSDN博客

35. Search Insert Position[Easy]

思路:經典二分,求大于等于當前數的第一個位置,果然easy題,那么直接來

/*
Author Owen_Q
*/
public class InsertSearcher {public static int searchInsert(int[] nums, int target) {int en = nums.length - 1;int st = 0;int mid = (st + en) / 2;while (st <= en) {if (nums[mid] == target) {return mid;} else if (nums[mid] > target) {en = mid - 1;} else {st = mid + 1;}mid = (st + en) / 2;}return st;}
}

多想一步:考慮元素可重通用寫法

?既然是easy題,這一題其實也很有代表性了,那么我們就多想一步,考慮一下當元素可重時的通用寫法,就是將等于mid的場景直接去掉。這樣就可以形成通用模板了,說不定后面還能用到

/*
Author Owen_Q
*/
public class InsertSearcher {public static int accurateSearchInsert(int[] nums, int target) {int en = nums.length - 1;int st = 0;while (st <= en) {int mid = (st + en) / 2;if (nums[mid] >= target) {en = mid - 1;} else {st = mid + 1;}}return st;}
}

33. Search in Rotated Sorted Array[Medium]

思路:將數組旋轉,然后求當前元素是否在數組中。經典二分的變種題,分情況討論一下即可

首先特判mid,st和en三個點,如果找到直接返回。

我們的目標就是為了找到target個mid的關系,從而縮小二分的區間

下面,我們主要討論值在左邊的場景,因為值在右邊的場景把值在左邊的場景排除掉即可獲得

首先,我們可以根據target和num[mid]的大小關系來進行分類,然后再根據mid在大小分界的左邊還是右邊進行分類

  • 當target<num[mid]時,
    • 我們先假設mid在分界的左側(num[en] < num[st] < num[mid]),那么此時mid的左側有序,此時如果希望target在mid左側,那么target一定得大于num[st],否則,若target再小一點就會轉到右邊去了,即target > num[st]?
    • 我們再假設num[mid]在分界的右側(num[mid] < num[en] < num[st] ),此時左側無序了,右側有序了,那么此時我們不難發現,這種情況肯定沒法在右側。于是只需要找到這種情況即可。即num[st] > num[mid]?
  • 當target>num[mid]時
    • 還是一樣,我們先假設mid在分界的左側(num[en] < num[st] < num[mid]),此時mid的左側有序,那么num[mid]就是最大值,而target比最大值還大,顯然不成立
    • 由此可知,此時mid一定在分界的右側(num[mid] < num[en] < num[st]),那么mid右側有序,此時,target值一定要大于num[st],確保其轉到左邊去
/*
Author Owen_Q
*/
public class RotatedSearcher {public static int search(int[] nums, int target) {int en = nums.length - 1;int st = 0;int mid = (st + en) / 2;while (st <= en) {if (nums[mid] == target) {return mid;} else if (nums[st] == target) {return st;} else if (nums[en] == target) {return en;} else if ((nums[mid] > target && ((nums[st] < target) || nums[st] > nums[mid])) || (nums[mid] < target && nums[mid] < nums[st] && nums[st] < target)) {en = mid - 1;} else {st = mid + 1;}mid = (st + en) / 2;}return -1;}
}

153. Find Minimum in Rotated Sorted Array[Medium]

思路:尋找旋轉數組中的最小值

依舊是分情況討論。

首先我們先找一種最簡單的情況,就是數組內部有序,即nums[st] \leqslant nums[mid] \leq nums[en],那么此時可以直接退出二分,因為st就是最小值所在點

接下來,我們看一下兩種常規情況?

第一種就是當前搜索到的值比兩側都大,即nums[mid] \geq nums[st] \wedge nums[mid] \geq nums[en],那么此時最小值一定在右側

第二種則是當搜索到的值比兩側都小,即nums[mid] \leq nums[st] \wedge nums[mid] \leq nums[en],那么此時最小值要么在左側,要么自身就是最小值

/*
Author Owen_Q
*/
public class RotatedMinimum {public static int findMin(int[] nums) {int st = 0;int en = nums.length - 1;int mid = (st + en) / 2;while (st <= en) {if (nums[st] <= nums[mid] && nums[mid] <= nums[en]) {return nums[st];} else if (nums[mid] >= nums[st] && nums[mid] >= nums[en]) {st = mid + 1;} else {en = mid;}mid = (st + en) / 2;}return nums[st];}
}

74. Search a 2D Matrix[Medium](詳見矩陣專題)

思路:這一題極其熟悉,是不是之前做過,果然,在矩陣專題里有原題,還是線性復雜度的,那既然有更好的做法,就不看這里log復雜度的二分方案了

Leetcode百題斬-矩陣-矩陣搜索-CSDN博客

34. Find First and Last Position of Element in Sorted Array[Medium]

思路:尋找元素在數組中的區間。這剛好上面多想一步的模版就可以用上了。模版的內容是找到大于等于當前數的第一個值,剛好可以作為區間起點,區間終點就是大于等于下一個數的前一個位置。若當前數不在區間中,那么大于等于當前數和大于等于下一個數一定是同一個位置,區間終點建議后會導致右區間大于左區間,直接特判找不到即可

/*
Author Owen_Q
*/
public class RangeSearcher {public static int[] searchRange(int[] nums, int target) {int[] result = new int[2];result[0] = InsertSearcher.accurateSearchInsert(nums, target);result[1] = InsertSearcher.accurateSearchInsert(nums, target + 1) - 1;if (result[0] > result[1]) {result[0] = -1;result[1] = -1;}return result;}
}

4. Median of Two Sorted Arrays[Hard]

思路:給定兩個有序數組,要求在log時間復雜度內尋找中位數。換個思路,尋找中位數,思路上來說就是尋找兩數組合并后的中間兩個數求個平均值。針對長度為?nums1Len?和?nums2Len?的數組,中間的位置就在?\frac{nums1Len + nums2Len}{2}?和?\frac{nums1Len + nums2Len - 1}{2}。于是,問題轉化為,如何求兩個有序數組的第?k?個位置的值。如果直接將倆數組合并,那妥妥線性復雜度,如何利用二分的思路將復雜度降下來呢?二分的思路一般就是每次將數據規模降低一半,恰巧,其實為了求第?k?個位置的數,其?\frac{k-1}{2}?位置的及前方的數一定位于同一個數組,那么比較倆數組?\frac{k-1}{2}?位置的數,并將小的直接舍棄,就做到了對半降低數據量。最終如果某個數組空了,或者不需要舍棄了,即可直接返回結果。這題最難的點就是對半邊界的取值,一不小心就會出現偏差,還是細致至上了。

/*
Author Owen_Q
*/
public class ArrayMedian {public static double findMedianSortedArrays(int[] nums1, int[] nums2) {int nums1Len = nums1.length;int nums2Len = nums2.length;int medianMin = (nums1Len + nums2Len - 1) / 2;int medianMax = (nums1Len + nums2Len) / 2;return ((double)getMedian(nums1, 0, nums1Len - 1, nums2, 0, nums2Len - 1, medianMin) + (double)getMedian(nums1,0, nums1Len - 1, nums2, 0, nums2Len - 1, medianMax)) / 2.0;}private static int getMedian(int[] nums1, int nums1Start, int nums1End, int[] nums2, int nums2Start, int nums2End,int pos) {if (nums1Start > nums1End) {return nums2[nums2Start + pos];}if (nums2Start > nums2End) {return nums1[nums1Start + pos];}if (pos == 0) {return Math.min(nums1[nums1Start + pos], nums2[nums2Start + pos]);}int num1pos = Math.min(nums1End, nums1Start + (pos - 1) / 2);int num2pos = Math.min(nums2End, nums2Start + (pos - 1) / 2);if (nums1[num1pos] <= nums2[num2pos]) {int newPos = pos + nums1Start - num1pos - 1;return getMedian(nums1, num1pos + 1, nums1End, nums2, nums2Start, nums2End, newPos);} else {int newPos = pos + nums2Start - num2pos - 1;return getMedian(nums1, nums1Start, nums1End, nums2, num2pos + 1, nums2End, newPos);}}
}

多想一步:拆分區間

其實上述思路是用到了log復雜度將數據量減半的思路,但其實還有一個更通用的二分方式,就是二分特定位置。

針對中位數,我們可以將數組拆分成左右兩個區間,要求兩個區間的元素數量完全相同,或者左側比右側少一個元素。并且要求左側的數一定都小于等于右側的數。此時,若數組大小為奇數,則右側最小值為中位數,否則,左側最大值和右側最小值的平均值即為中位數。

那么問題就簡化為了,如何尋找到劃分區間的位置。首先,我們可以將短的數組作為操作數組,因為只要短的數組的劃分位置定了,那么根據元素數量就一定能算出長的數組的劃分位置。假設數組1的長度為?nums1Len,數組2的長度為?nums2Len,數組1的劃分位置為?mid,那么數組2的劃分位置就是?(nums1Len + nums2Len) / 2 - mid。于是我們二分短的數組的劃分位置,即可得到長數組的劃分位置,再檢查一下是否左邊最大值小于等于右邊最小值即可。至于二分移動方案,若左上大于右下,則劃分位置需要向左移,否則向右移。最后注意一下當劃分位置移動到邊界時,那么邊界的數如果不存在則不參與比較,可能用個int的最大值和最小值來跳過比較即可。

/*
Author Owen_Q
*/
public class ArrayMedian {public static double findMedianSortedArraysByDivider(int[] nums1, int[] nums2) {int nums1Len = nums1.length;int nums2Len = nums2.length;if (nums1Len > nums2Len) {return findMedianSortedArraysByDivider(nums2, nums1);}int st = 0;int en = nums1Len;int medianMin = 0;int medianMax = nums1Len - 1;while (st <= en) {int mid = (st + en) / 2;int mid2 = (nums1Len + nums2Len) / 2 - mid;int left1 = mid == 0 ? Integer.MIN_VALUE : nums1[mid - 1];int left2 = mid2 == 0 ? Integer.MIN_VALUE : nums2[mid2 - 1];int right1 = mid == nums1Len ? Integer.MAX_VALUE : nums1[mid];int right2 = mid2 == nums2Len ? Integer.MAX_VALUE : nums2[mid2];medianMin = Math.max(left1, left2);medianMax = Math.min(right1, right2);if (medianMin <= medianMax) {break;} else if (left1 > right2) {en = mid - 1;} else {st = mid + 1;}}if ((nums1Len + nums2Len) % 2 == 1) {return medianMax;} else {return (double)(medianMin + medianMax) / 2.0;}}
}

最終,二分也完結撒花了

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

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

相關文章

【IDEA】格式化代碼工具配置

格式化代碼快捷鍵&#xff1a; CtrlAltL格式代碼的時候不會再方法名與參數中間添加空格默認不勾選的情況下&#xff1a;代碼樣例&#xff1a;勾選之后的樣例&#xff1a;選擇不勾選&#xff0c;IDEA默認情況下就是不勾選的狀態忽略加載文件有些非必要加載到開發工具中的文件我們…

驅動開發(3)|rk356x驅動GPIO基礎應用之點亮led燈

點亮LED燈看似是一個基礎的操作&#xff0c;但實際上&#xff0c;許多高級應用也依賴于高低電平的切換。例如&#xff0c;脈沖寬度調制&#xff08;PWM&#xff09;信號可以用來精確控制電機的轉速&#xff0c;通過改變脈沖的頻率和占空比&#xff0c;實現對電機的精確調節&…

手動搭建PHP環境:步步為營,解鎖Web開發

目錄一、引言二、準備工作2.1 明確所需軟件2.2 下載軟件三、Windows 系統搭建步驟3.1 安裝 Apache 服務器3.2 安裝 PHP3.3 集成 Apache 與 PHP3.4 安裝 MySQL3.5 配置 PHP 連接 MySQL四、Linux 系統搭建步驟&#xff08;以 Ubuntu 為例&#xff09;4.1 更新系統4.2 安裝 Apache…

DrissionPage:一款讓網頁自動化更簡單的 Python 庫

在網頁自動化領域&#xff0c;Selenium 和 Playwright 早已是開發者耳熟能詳的工具。但今天要給大家介紹一款更輕量、更易用的 Python 庫 ——DrissionPage。它以 "融合 selenium 和 requests 優勢" 為核心設計理念&#xff0c;既能像 requests 一樣高效處理靜態網頁…

理解Grafana中`X-Scope-OrgID`的作用與配置

X-Scope-OrgID的作用 該HTTP Header用于標識Loki日志數據的所屬租戶&#xff08;組織&#xff09;。在多租戶模式下&#xff0c;Loki通過此Header隔離不同團隊或用戶的數據&#xff0c;確保查詢和存儲的獨立性。數據隔離&#xff1a; 租戶A的日志標記為X-Scope-OrgID: team-a&a…

【PycharmPyqt designer桌面程序設計】

在 main.py 中調用 Qt Designer 生成的 windows.py&#xff08;假設它是 PySide2 版&#xff09;。 只要把兩個文件放在同一目錄即可直接運行。 ──────────────────── 1?? windows.py&#xff08;Qt Designer 生成&#xff0c;已轉碼&#xff09; # -*-…

Unity Android Logcat插件 輸出日志中文亂碼解決

背景之前安卓真機調試看日志&#xff0c;一直用的是Android Studio自帶的adb命令進行看日志&#xff0c;不太方便&#xff0c;改用Unity自帶的安卓日志插件時&#xff0c;存在中文日志亂碼問題。插件安裝基于Unity6000.1.11版本&#xff1a;Window -> Package Management -&…

Halcon雙相機單標定板標定實現拼圖

1.Halcon圖像拼接算法在之前的文章里也寫過&#xff0c;主要是硬拼接和特征點拼接兩種方式&#xff0c;今天增加另一種拼接圖像的方式。應用場景是多個相機聯合一起拍大尺寸的物體&#xff0c;并且相機視野之間存在重疊區域。通過在同一個標定板上面標定&#xff0c;計算兩個相…

動物世界一語乾坤韻芳華 人工智能應用大學畢業論文 -仙界AI——仙盟創夢IDE

提示詞在一個奇幻的童話森林里&#xff0c;所有的動物都像人類一樣直立行走&#xff0c;穿著各種搞怪的衣服。 一只戴著超大眼鏡、穿著背帶褲的烏龜&#xff0c;正一本正經地站在一個蘑菇舞臺上&#xff0c;拿著一根樹枝當作麥克風&#xff0c;準備唱歌。它的眼鏡總是往下滑&am…

SpringBoot(原理篇)

大家好&#xff0c;這里是 盛碼筆記。 本篇我們來聊一聊 Spring Boot 的“魔法”是如何實現的。你可能已經用過 Spring Boot 快速搭建項目&#xff0c;但有沒有想過&#xff1a;為什么只需要引入幾個 starter&#xff0c;Spring Boot 就能自動配置好整個應用環境&#xff1f; …

數據結構:棧(區間問題)

碼蹄集OJ-小碼哥的棧 #include<bits/stdc.h> using namespace std; #define int long long const int N1e67; struct MOOE {int ll,rr; }; stack<MOOE>st; signed main( ) {ios::sync_with_stdio(false);cin.tie(nullptr);int n;cin>>n;while(n--){int opt…

Vue 中 data、watch、created 和 methods

以下是 Vue 中 data、watch、created 和 methods 的詳細解釋&#xff0c;結合常見使用場景和示例&#xff1a;1. data&#xff1a;響應式數據容器 作用&#xff1a;定義組件的響應式數據&#xff08;狀態&#xff09;&#xff0c;當數據變化時&#xff0c;視圖自動更新。特點&a…

精密模具冷卻孔內輪廓檢測方法探究 —— 激光頻率梳 3D 輪廓檢測

引言精密模具冷卻孔的內輪廓精度直接影響注塑成型效率與制品質量。冷卻孔具有深徑比大&#xff08;可達 25:1&#xff09;、結構復雜&#xff08;多為螺旋形或異形&#xff09;、表面質量要求高&#xff08;Ra≤0.2μm&#xff09;等特點&#xff0c;傳統檢測方法難以滿足其高精…

Vue單文件組件與腳手架工程化開發

一、Vue與VueComponent原型關系解析1. 原型鏈關系圖解在Vue中&#xff0c;組件實例(VueComponent)與Vue實例之間存在特殊的原型鏈關系&#xff1a;VueComponent.prototype.__proto__ Vue.prototype這種設計使得所有組件都能訪問Vue原型上定義的方法和屬性。2. 原理驗證示例// …

架構設計之計算高性能——單體服務器高性能

架構設計之計算高性能——單體服務器高性能 高性能是每個程序員共同的追求&#xff0c;無論是開發系統&#xff0c;還是僅僅只是寫一段腳本&#xff0c;都希望能夠達到高性能的效果&#xff0c;而高性能又是軟件系統設計中最復雜的一步。無論是開發千萬級并發的電商系統&#…

Unity燈光面板環境設置

在Unity中&#xff0c;環境設置&#xff08;Environment Lighting&#xff09; 是燈光面板&#xff08;Lighting Window&#xff09;的核心功能之一&#xff0c;用于控制場景的全局光照效果&#xff0c;包括天空盒、環境光、反射和霧效等。這些設置直接影響場景的整體氛圍和真實…

MySQL語句優化案例

1.案例in查詢條件很慢其中in中共115個select id,detail_id,request,response,utime,ctime from response_detaill where detaill_id in (26371986, 26372242, 26371984, 26371990, 26400150, 26371988, 26371994, 26371992,26371998, 26371996, 26371970, 26371968, 2637197…

能行為監測算法:低成本下的高效管理

AI監控智慧公司管理&#xff1a;降本增效的實踐與突破一、背景&#xff1a;經濟壓力下的管理轉型需求在經濟下行周期&#xff0c;企業面臨人力成本攀升、管理效率低下、安全風險頻發等多重挑戰。傳統監控依賴人工巡檢&#xff0c;存在響應滯后、誤判率高、數據孤島等問題&#…

當前(2024-07-14)視頻插幀(VFI)方向的 SOTA 基本被三篇頂會工作占據,按“精度-速度-感知質量”三條線總結如下,供你快速定位最新范式

當前&#xff08;2024-07-14&#xff09;視頻插幀&#xff08;VFI&#xff09;方向的 SOTA 基本被三篇頂會工作占據&#xff0c;按“精度-速度-感知質量”三條線總結如下&#xff0c;供你快速定位最新范式。感知質量最佳&#xff1a;CVPR 2024 ? PerVFI ? 關鍵詞&#xff1a;…

開源 python 應用 開發(七)數據可視化

最近有個項目需要做視覺自動化處理的工具&#xff0c;最后選用的軟件為python&#xff0c;剛好這個機會進行系統學習。短時間學習&#xff0c;需要快速開發&#xff0c;所以記錄要點步驟&#xff0c;防止忘記。 鏈接&#xff1a; 開源 python 應用 開發&#xff08;一&#xf…