LeetCode 4:尋找兩個正序數組的中位數

LeetCode 4:尋找兩個正序數組的中位數

在這里插入圖片描述

問題定義與核心挑戰

給定兩個有序(升序)數組 nums1nums2,要求找到它們的中位數,且算法時間復雜度為 O(log(m+n))mn 分別是兩個數組的長度)。

中位數定義

  • 若合并后數組長度為奇數,中位數是中間位置的元素(如 [1,2,3] 的中位數是 2)。
  • 若合并后數組長度為偶數,中位數是中間兩個元素的平均值(如 [1,2,3,4] 的中位數是 (2+3)/2=2.5)。

常規方法的不足

若直接合并兩個數組(時間復雜度 O(m+n)),雖能解決問題,但無法滿足題目對時間復雜度的嚴格要求(O(log(m+n)))。因此,必須利用數組有序的特性,通過 二分查找 避免完全合并。

核心思路:二分法定位分割點

中位數的本質是將合并后的數組劃分為左右兩部分,使得:

  • 左邊所有元素 ≤ 右邊所有元素;
  • 左邊元素個數 ≥ 右邊(奇數長度時左邊多一個)。

對于兩個有序數組,我們可以通過二分查找分割點,將 nums1nums2 分別劃分為左右兩部分,使得:

  • nums1 的左半部分 + nums2 的左半部分 nums1 的右半部分 + nums2 的右半部分;
  • 左半部分總元素數為 (m+n+1)//2(向上取整,保證奇數長度時左邊多一個)。

算法步驟詳解

步驟 1:統一數組長度(優化二分范圍)

為了減少二分查找的范圍,確保 nums1 是較短的數組(若 nums1 更長,則交換 nums1nums2)。這樣,二分查找僅需在較短數組上進行,降低時間復雜度。

int m = nums1.length, n = nums2.length;
if (m > n) {// 交換數組,確保 nums1 是較短的int[] temp = nums1;nums1 = nums2;nums2 = temp;m = nums1.length;n = nums2.length;
}
步驟 2:二分查找分割點

nums1 中二分查找分割點 i,并計算 nums2 的對應分割點 j

  • i 表示 nums1 左半部分的元素個數(范圍:0 ≤ i ≤ m);
  • j = (m + n + 1) // 2 - i,保證左半部分總元素數為 (m+n+1)//2(向上取整)。
int left = 0, right = m;
while (left < right) {// 向上取整,避免死循環(如 left=1, right=2 時,mid=2)int mid = (left + right + 1) / 2; int j = (m + n + 1) / 2 - mid;if (nums1[mid-1] > nums2[j]) {// i 太大,左移右邊界right = mid - 1;} else {// i 太小,右移左邊界left = mid;}
}
int i = left;
int j = (m + n + 1) / 2 - i;
步驟 3:處理邊界值(分割點越界)

分割點 ij 可能為 0(左半部分為空)或等于數組長度(右半部分為空),需用極值(-∞+∞)處理:

// nums1 左半部分的最大值(i=0 時,左半部分為空,設為 -∞)
double nums1_left = (i == 0) ? Integer.MIN_VALUE : nums1[i-1];
// nums1 右半部分的最小值(i=m 時,右半部分為空,設為 +∞)
double nums1_right = (i == m) ? Integer.MAX_VALUE : nums1[i];
// nums2 左半部分的最大值(j=0 時,左半部分為空,設為 -∞)
double nums2_left = (j == 0) ? Integer.MIN_VALUE : nums2[j-1];
// nums2 右半部分的最小值(j=n 時,右半部分為空,設為 +∞)
double nums2_right = (j == n) ? Integer.MAX_VALUE : nums2[j];
步驟 4:計算中位數

根據合并后數組的長度(m+n)的奇偶性,計算中位數:

  • 奇數:左半部分最大值(max(nums1_left, nums2_left));
  • 偶數:左半部分最大值與右半部分最小值的平均值((max(...) + min(...)) / 2)。
if ((m + n) % 2 == 1) {// 奇數長度,中位數是左半部分最大值return Math.max(nums1_left, nums2_left);
} else {// 偶數長度,中位數是左右部分的中間值平均return (Math.max(nums1_left, nums2_left) + Math.min(nums1_right, nums2_right)) / 2.0;
}

完整代碼(Java)

class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int m = nums1.length, n = nums2.length;// 確保 nums1 是較短的數組,優化二分范圍if (m > n) {int[] temp = nums1;nums1 = nums2;nums2 = temp;m = nums1.length;n = nums2.length;}int left = 0, right = m;while (left < right) {// 向上取整,避免死循環int mid = (left + right + 1) / 2; int j = (m + n + 1) / 2 - mid;if (nums1[mid - 1] > nums2[j]) {// i 太大,左移右邊界right = mid - 1;} else {// i 太小,右移左邊界left = mid;}}int i = left;int j = (m + n + 1) / 2 - i;// 處理邊界值:左半部分或右半部分為空的情況double nums1_left = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];double nums1_right = (i == m) ? Integer.MAX_VALUE : nums1[i];double nums2_left = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];double nums2_right = (j == n) ? Integer.MAX_VALUE : nums2[j];// 計算中位數if ((m + n) % 2 == 1) {return Math.max(nums1_left, nums2_left);} else {return (Math.max(nums1_left, nums2_left) + Math.min(nums1_right, nums2_right)) / 2.0;}}
}

關鍵邏輯解析

1. 數組交換的意義

將較長數組與較短數組交換,確保二分查找在較短數組上進行,減少二分次數(如 m=3, n=5 時,二分范圍是 0~3 而非 0~5)。

2. 分割點的數學意義

j = (m + n + 1) // 2 - i 保證 左半部分總元素數為 (m+n+1)//2

  • m+n 為奇數,左半部分比右半部分多 1 個元素,中位數是左半部分的最大值;
  • m+n 為偶數,左半部分與右半部分元素數相等,中位數是兩部分的中間值平均。
3. 邊界值處理

通過 Integer.MIN_VALUEInteger.MAX_VALUE 處理“左半部分為空”或“右半部分為空”的情況,確保比較邏輯的一致性。

4. 二分循環的細節

使用 (left + right + 1) / 2 向上取整,避免 leftright 相鄰時的死循環(如 left=1, right=2 時,mid=2 而非 1,確保范圍縮小)。

該方法通過 二分查找分割點 避免了數組的完全合并,將時間復雜度優化到 O(log(min(m,n)))(等價于 O(log(m+n))),是處理“兩個有序數組中位數”問題的經典方案。

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

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

相關文章

獨立站如何吃掉平臺蛋糕?DTC模式下的成本重構與利潤躍升

一、成本結構革命&#xff1a;從「流量稅」到「用戶終身價值」亞馬遜賣家需支付15%傭金12%廣告費&#xff0c;導致每$100收入中平臺抽成$27。而成熟獨立站通過SEO&#xff08;自然流量占比超40%&#xff09;和社交媒體內容引流&#xff0c;將獲客成本壓縮至$8-$15。更關鍵的是用…

應用驅動 協同創新:中國人工智能開啟高質量發展新篇章

人工智能技術的突破性發展正引發全球產業格局的深刻變革。在2025年這個關鍵節點&#xff0c;中國以"應用導向"為戰略支點&#xff0c;依托新型舉國體制優勢&#xff0c;正在構建具有中國特色的人工智能發展體系&#xff0c;為全球智能革命貢獻東方智慧。一、戰略布局…

ZKMall商城開源本地部署指南

1. 開發環境配置 以下是開發工具的最低版本要求。在繼續之前&#xff0c;請務必安裝所有必需的依賴項。 工具版本JDK17MySQL5.7.3Redis5.0Maven3.9.5NodeJS20.18.0 1.1 安裝資源 如需詳細的安裝指南&#xff0c;您可以參考以下教程&#xff1a; JDK: 菜鳥教程 Java 環境搭建…

《使用Qt Quick從零構建AI螺絲瑕疵檢測系統》——8. AI賦能(下):在Qt中部署YOLOv8模型

目錄一、概述1.1 背景介紹&#xff1a;從“訓練”到“部署”1.2 學習目標二、在C中集成ONNX模型2.1 準備模型文件2.2 修改Backend以加載和運行模型三、關鍵一步&#xff1a;輸出結果的后處理四、運行與驗證五、總結與展望一、概述 1.1 背景介紹&#xff1a;從“訓練”到“部署…

【動態規劃 | 多狀態問題】動態規劃求解多狀態問題

算法相關知識點可以通過點擊以下鏈接進行學習一起加油&#xff01;斐波那契數列模型路徑問題多狀態問題通常涉及多個決策點和狀態轉換&#xff0c;解決起來復雜且計算量大。動態規劃作為一種強大的算法工具&#xff0c;能夠通過將問題分解為子問題并逐步求解&#xff0c;顯著提…

【HTTP】防XSS+SQL注入:自定義HttpMessageConverter過濾鏈深度解決方案

防XSSSQL注入&#xff1a;自定義HttpMessageConverter過濾鏈深度解決方案一、安全威脅模型分析二、自定義HttpMessageConverter架構設計2.1 技術棧組成三、完整實現代碼3.1 安全過濾工具類3.2 自定義HttpMessageConverter3.3 Spring安全配置四、深度防御增強方案4.1 SQL注入參數…

學習游戲制作記錄(凍結敵人時間與黑洞技能)7.30

1.實現劍擊中敵人時凍結敵人時間Enemy腳本&#xff1a;public float defaultMoveSpeed;//默認速度defaultMoveSpeed moveSpeed;//Awake&#xff08;&#xff09;中設置public virtual void FreezeTime(bool _timeFreeze)//凍結設置函數{if (_timeFreeze){moveSpeed 0;anim.sp…

【數據結構】真題 2016

待補充已知表頭元素為c的單鏈表在內存中的存儲狀態如下表所示地址元素鏈接地址1000Ha1010H1004Hb100CH1008Hc1000H100CHdNULL1010He1004H1014H現將f存放于1014H處并插入到單鏈表中&#xff0c;若f在邏輯上位于a和e之間&#xff0c;則a, e, f的“鏈接地址”依次是&#xff08; &…

雙線串行的 “跨界對話”:I2C 與 MDIO 的異同解析

在電子系統設計中,串行總線憑借其精簡的信號線數量和靈活的拓撲結構,成為芯片間通信的主流選擇。I2C(Inter-Integrated Circuit)和 MDIO(Management Data Input/Output)作為兩種典型的雙線串行總線,雖同屬低速信號范疇,卻在各自的應用領域扮演著不可替代的角色。本文將…

算法精講:二分查找(二)—— 變形技巧

&#x1f3af; 算法精講&#xff1a;二分查找&#xff08;二&#xff09;—— 變形技巧 &#x1f50d; 友情提示&#xff1a;&#xff1a;本小節含高能代碼片段 &#x1f964; 閱讀前請確保已掌握基礎二分原理與實現代碼片段可能包含不同程度的變形&#xff0c;請根據實際情況選…

兩個程序配合實現了基于共享內存和信號量的進程間通信,具體說明如下:

第一個程序&#xff1a;共享內存讀取程序&#xff08;消費者&#xff09;該程序作為消費者&#xff0c;從共享內存中讀取數據&#xff0c;通過信號量保證只有當生產者寫入數據后才能讀取。/*4 - 讀共享內存*/ #include<stdio.h> // 標準輸入輸出庫 #inc…

JeecgBoot(1):前后臺環境搭建

1 項目介紹 JeecgBoot 是一款基于 Java 的 AI 低代碼平臺&#xff0c;它采用了 SpringBoot、SpringCloud、Ant Design Vue3、Mybatis 等技術棧&#xff0c;并集成了代碼生成器、AI 對話助手、AI 建表、AI 寫文章等功能。JeecgBoot 的設計宗旨是實現簡單功能零代碼開發&#xf…

Nestjs框架: 關于 OOP / FP / FRP 編程

概述 在軟件開發過程中&#xff0c;不同的編程范式為我們提供了多樣化的思維方式與實現路徑它們不僅影響著代碼的結構和邏輯組織方式&#xff0c;也深刻影響著項目的可維護性、可擴展性以及團隊協作效率 什么是 OOP、FP 和 FRP&#xff1f;首先從三個術語的含義入手 1 &#xf…

elememtor 添加分頁功能

各位看官好&#xff0c;最近在忙著使用elementor搭建自己的網站&#xff0c;由于我不是專業的程序員和前端&#xff0c;又沒有很多錢去找外包公司實現自己的設計&#xff0c;所以選擇了elementor. 總的來說這是一個不錯的wordpress 插件&#xff0c;也讓我們這種非專業的網站設…

關于“PromptPilot” 之2 -目標系統:Prompt構造器

目標系統&#xff1a;Prompt構造器想法首先&#xff0c;在抽象層對PromptPilot進行封裝給出提示詞形成過程的全部環節。然后&#xff0c;在 形成一套確定的提示詞后再為 小規模試點方案生成一整套開發工具并配套集成開發環境和指南。最后&#xff0c;在小規模試點成功后進行拓展…

短劇小程序系統開發:重塑影視內容消費格局

在數字化浪潮的推動下&#xff0c;影視內容消費正經歷著深刻的變革。短劇小程序系統開發作為這一變革的重要力量&#xff0c;正在重塑影視內容消費的格局&#xff0c;為用戶帶來更加個性化、便捷化的觀影體驗。傳統影視內容消費往往受到時間和空間的限制&#xff0c;用戶需要前…

一文掌握最新版本Monocle3單細胞軌跡(擬時序)分析

許多大佬的軟件想要構建一個大而美的生態&#xff0c;從 monocle2 開始就能做單細胞的質控、降維、分群、注釋這一系列的分析&#xff0c;但不幸的是我們只知道 monocle 系列還是主要做擬時序分析&#xff0c;一方面是因為 Seurat 有先發優勢&#xff0c;出名要趁早&#xff0c…

spark入門-helloword

我們學習編程語言的時候&#xff0c;第一個程序就是打印一下 “hello world” &#xff0c;對于大數據領域的第一個任務則是wordcount。那我們就開始我們的第一個spark任務吧&#xff01; 下載spark 官方下載地址&#xff1a;Apache Download Mirrors 下載完畢以后&#xff0c…

雷達系統設計學習:自制6GHz FMCW Radar

國外大神自制6GHZ FMCW Radar開源項目: https://github.com/Ttl/fmcw3 引言 之前我做過一個簡單的調頻連續波&#xff08;FMCW&#xff09;雷達&#xff0c;能夠探測到100米范圍內人體大小的物體。雖然它確實能用&#xff0c;但由于預算有限&#xff0c;還有很大的改進空間。 …

系統選擇菜單(ubuntu grub)介紹

好的&#xff0c;我們來詳細解釋一下什么是Ubuntu的GRUB菜單。 簡單來說&#xff0c;GRUB菜單是您電腦啟動時看到的第一個交互界面&#xff0c;它就像一個“系統選擇”菜單&#xff0c;讓您決定接下來要啟動哪個操作系統或進入哪種模式。詳細解釋 1. GRUB是什么&#xff1f; GR…