LeetCode Hot 100 尋找兩個正序數組的中位數

給定兩個大小分別為?m?和?n?的正序(從小到大)數組?nums1?和?nums2。請你找出并返回這兩個正序數組的?中位數?。

算法的時間復雜度應該為?O(log (m+n))?。

示例 1:

輸入:nums1 = [1,3], nums2 = [2]
輸出:2.00000
解釋:合并數組 = [1,2,3] ,中位數 2

示例 2:

輸入:nums1 = [1,2], nums2 = [3,4]
輸出:2.50000
解釋:合并數組 = [1,2,3,4] ,中位數 (2 + 3) / 2 = 2.5

給定兩個有序數組,要求找到兩個有序數組的中位數,最直觀的思路有以下兩種:

使用歸并的方式,合并兩個有序數組,得到一個大的有序數組。大的有序數組的中間位置的元素,即為中位數。

不需要合并兩個有序數組,只要找到中位數的位置即可。由于兩個數組的長度已知,因此中位數對應的兩個數組的下標之和也是已知的。維護兩個指針,初始時分別指向兩個數組的下標 0 的位置,每次將指向較小值的指針后移一位(如果一個指針已經到達數組末尾,則只需要移動另一個數組的指針),直到到達中位數的位置。

假設兩個有序數組的長度分別為 m 和 n,上述兩種思路的復雜度如何?

第一種思路的時間復雜度是 O(m+n),空間復雜度是 O(m+n)。第二種思路雖然可以將空間復雜度降到 O(1),但是時間復雜度仍是 O(m+n)。

如何把時間復雜度降低到 O(log(m+n)) 呢?如果對時間復雜度的要求有 log,通常都需要用到二分查找,這道題也可以通過二分查找實現。

根據中位數的定義,當 m+n 是奇數時,中位數是兩個有序數組中的第 (m+n)/2 個元素,當 m+n 是偶數時,中位數是兩個有序數組中的第 (m+n)/2 個元素和第 (m+n)/2+1 個元素的平均值。因此,這道題可以轉化成尋找兩個有序數組中的第 k 小的數,其中 k 為 (m+n)/2 或 (m+n)/2+1。

假設兩個有序數組分別是 A 和 B。要找到第 k 個元素,我們可以比較 A[k/2?1] 和 B[k/2?1],其中 / 表示整數除法。由于 A[k/2?1] 和 B[k/2?1] 的前面分別有 A[0..k/2?2] 和 B[0..k/2?2],即 k/2?1 個元素,對于 A[k/2?1] 和 B[k/2?1] 中的較小值,最多只會有 (k/2?1)+(k/2?1)≤k?2 個元素比它小,那么它就不能是第 k 小的數了。

因此我們可以歸納出三種情況:

如果 A[k/2?1]<B[k/2?1],則比 A[k/2?1] 小的數最多只有 A 的前 k/2?1 個數和 B 的前 k/2?1 個數,即比 A[k/2?1] 小的數最多只有 k?2 個,因此 A[k/2?1] 不可能是第 k 個數,A[0] 到 A[k/2?1] 也都不可能是第 k 個數,可以全部排除。

如果 A[k/2?1]>B[k/2?1],則可以排除 B[0] 到 B[k/2?1]。

如果 A[k/2?1]=B[k/2?1],則可以歸入第一種情況處理。

可以看到,比較 A[k/2?1] 和 B[k/2?1] 之后,可以排除 k/2 個不可能是第 k 小的數,查找范圍縮小了一半。同時,我們將在排除后的新數組上繼續進行二分查找,并且根據我們排除數的個數,減少 k 的值,這是因為我們排除的數都不大于第 k 小的數。

有以下三種情況需要特殊處理:

如果 A[k/2?1] 或者 B[k/2?1] 越界,那么我們可以選取對應數組中的最后一個元素。在這種情況下,我們必須根據排除數的個數減少 k 的值,而不能直接將 k 減去 k/2。

如果一個數組為空,說明該數組中的所有元素都被排除,我們可以直接返回另一個數組中第 k 小的元素。

如果 k=1,我們只要返回兩個數組首元素的最小值即可。

用一個例子說明上述算法。假設兩個有序數組如下:

A: 1 3 4 9
B: 1 2 3 4 5 6 7 8 9
兩個有序數組的長度分別是 4 和 9,長度之和是 13,中位數是兩個有序數組中的第 7 個元素,因此需要找到第 k=7 個元素。

比較兩個有序數組中下標為 k/2?1=2 的數,即 A[2] 和 B[2],如下面所示:

A: 1 3 4 9

B: 1 2 3 4 5 6 7 8 9

由于 A[2]>B[2],因此排除 B[0] 到 B[2],即數組 B 的下標偏移(offset)變為 3,同時更新 k 的值:k=k?k/2=4。

下一步尋找,比較兩個有序數組中下標為 k/2?1=1 的數,即 A[1] 和 B[4],如下面所示,其中方括號部分表示已經被排除的數。

A: 1 3 4 9

B: [1 2 3] 4 5 6 7 8 9

由于 A[1]<B[4],因此排除 A[0] 到 A[1],即數組 A 的下標偏移變為 2,同時更新 k 的值:k=k?k/2=2。

下一步尋找,比較兩個有序數組中下標為 k/2?1=0 的數,即比較 A[2] 和 B[3],如下面所示,其中方括號部分表示已經被排除的數。

A: [1 3] 4 9

B: [1 2 3] 4 5 6 7 8 9

由于 A[2]=B[3],根據之前的規則,排除 A 中的元素,因此排除 A[2],即數組 A 的下標偏移變為 3,同時更新 k 的值: k=k?k/2=1。

由于 k 的值變成 1,因此比較兩個有序數組中的未排除下標范圍內的第一個數,其中較小的數即為第 k 個數,由于 A[3]>B[3],因此第 k 個數是 B[3]=4。

A: [1 3 4] 9

B: [1 2 3] 4 5 6 7 8 9

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {if (nums1.size() > nums2.size()) {return findMedianSortedArrays(nums2, nums1);}int m = nums1.size();int n = nums2.size();int left = 0, right = m;// median1:前一部分的最大值// median2:后一部分的最小值int median1 = 0, median2 = 0;while (left <= right) {// 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]// 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]int i = (left + right) / 2;int j = (m + n + 1) / 2 - i;// nums_im1, nums_i, nums_jm1, nums_j 分別表示 nums1[i-1], nums1[i], nums2[j-1], nums2[j]int nums_im1 = (i == 0 ? INT_MIN : nums1[i - 1]);int nums_i = (i == m ? INT_MAX : nums1[i]);int nums_jm1 = (j == 0 ? INT_MIN : nums2[j - 1]);int nums_j = (j == n ? INT_MAX : nums2[j]);if (nums_im1 <= nums_j) {median1 = max(nums_im1, nums_jm1);median2 = min(nums_i, nums_j);left = i + 1;} else {right = i - 1;}}return (m + n) % 2 == 0 ? (median1 + median2) / 2.0 : median1;}
};

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

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

相關文章

監控場景視頻質量異常修復:陌訊動態增強算法實戰解析

原創聲明&#xff1a;本文為原創技術解析&#xff0c;核心技術參數與架構引用自《陌訊技術白皮書》&#xff0c;禁止未經授權轉載。一、行業痛點&#xff1a;視頻質量異常的連鎖難題在安防監控、智慧交通等場景中&#xff0c;視頻質量異常已成為 AI 分析的主要瓶頸。據行業報告…

一個簡單的mvvm示例與數據雙向綁定

這就是一個簡單的數據雙向綁定的demo&#xff0c;參考即可&#xff08;cmakelist我沒按他的寫&#xff0c;但是大差不差&#xff09; 目錄 1.示例demo File: CMakeLists.txt File: main.cpp File: model/physiologymodel.cpp File: viewmodel/physiologyviewmodel.h Fil…

哈希的概念及其應用

哈希的概念及其應用哈希概念常見的哈希其他哈希字符串哈希&#xff08;算法競賽常用&#xff09;字符串哈希OJP3370 【模板】字符串哈希 - 洛谷P10468 兔子與兔子 - 洛谷哈希沖突哈希函數設計原則哈希沖突解決方法—閉散列閉散列的線性探測閉散列的二次探測哈希沖突解決方法—開…

【分布式的個人博客部署】

綜合項目-搭建個人博客一、運行環境二、基礎配置三、業務需求第一步&#xff1a;準備工作1、配置靜態IP2、修改hosts映射3、開啟防火墻4、時間同步5、配置免密ssh登錄第二步&#xff1a;環境搭建1、Server-web端安裝LNMP環境軟件2、Server-NFS-DNS端上傳博客軟件3、Server-NFS-…

藍橋杯----DS18B20溫度傳感器

&#xff08;二&#xff09;、溫度傳感器1、One-Wire總線One-Wire總線利用一根線實現雙向通信。因此其協議對時序的要求較嚴格&#xff0c;如應答等時序都有明確的時間要求。基本的時序包括復位及應答時序、寫一位時序讀一位時序。單總線即只有一根數據線&#xff0c;系統中的數…

科技賦能成長 腦力啟迪未來

——西安臻昊科技與秦嶺云數智共筑腦科學教育新生態 2025年6月26日&#xff0c;西安臻昊科技&#xff08;集團&#xff09;有限責任公司與秦嶺云數智&#xff08;陜西&#xff09;科技有限公司正式簽署腦象評測技術戰略合作協議&#xff0c;雙方將依托技術互補與資源協同&#…

Docker部署的PostgreSQL慢查詢日志配置指南

目錄 1. 核心步驟 1.1 修改配置文件 1.2 動態加載配置&#xff08;無需重啟容器&#xff09; 1.3 驗證配置生效 1.3.1 查看參數 1.3.2 執行測試慢查詢 2. 高級用法 2.1 使用分析工具 2.2 啟用擴展 3. 注意事項 3.1 日志目錄權限 3.2 性能影響 配置Docker部署的Pos…

C# 入門教程(四)委托詳解

文章目錄1、什么是委托2、委托的聲明&#xff08;自定義委托&#xff09;3、委托的使用3.1 實例:把方法當作參數傳給另一個方法3.2 注意:難精通易使用功能強大東西&#xff0c;一旦被濫用則后果非常嚴重4、委托的高級使用4.1 多播&#xff08;multicast&#xff09;委托4.2隱式…

React的基本語法和原理

3. React條件渲染某些情況下&#xff0c;姐妹的內容會根據不同的情況顯示不同的內容&#xff0c;或者決定是否渲染某部分內容&#xff1a; 在React中&#xff0c;所有的條件判斷和普通的JavaScript代碼一致&#xff1b;常見的條件渲染的方式有哪些&#xff1f;方式一&#xff1…

如何在 Gradle 項目中添加依賴?(以添加 AndroidX 版本的 RecyclerView 為例)

1. 確保項目已啟用 AndroidX RecyclerView 的現代版本屬于 AndroidX 庫&#xff0c;需確保項目已啟用 AndroidX&#xff1a; 在 gradle.properties 中應有以下配置&#xff08;通常新建項目默認開啟&#xff09;&#xff1a;android.useAndroidXtrue android.enableJetifiert…

深度學習與圖像處理 | 基于PaddlePaddle的梯度下降算法實現(線性回歸投資預測)

演示基于PaddlePaddle自動求導技術實現梯度下降&#xff0c;簡化求解過程。01、梯度下降法梯度下降法是機器學習領域非常重要和具有代表性的算法&#xff0c;它通過迭代計算來逐步尋找目標函數極小值。既然是一種迭代計算方法&#xff0c;那么最重要的就是往哪個方向迭代&#…

負載均衡集群HAproxy

HAProxy 簡介HAProxy 是一款高性能的負載均衡器和代理服務器&#xff0c;支持 TCP 和 HTTP 應用。廣泛用于高可用性集群&#xff0c;能夠有效分發流量到多個后端服務器&#xff0c;確保服務的穩定性和可擴展性。HAProxy 核心功能負載均衡&#xff1a;支持輪詢&#xff08;round…

重生之我在10天內卷贏C++ - DAY 1

坐穩了&#xff0c;我們的C重生之旅現在正式發車&#xff01;請系好安全帶&#xff0c;前方高能&#xff0c;但絕對有趣&#xff01;&#x1f680; 重生之我在10天內卷贏C - DAY 1導師寄語&#xff1a;嘿&#xff0c;未來的編程大神&#xff01;歡迎來到C的世界。我知道&#x…

[mind-elixir]Mind-Elixir 的交互增強:單擊、雙擊與鼠標 Hover 功能實現

[mind-elixir]Mind-Elixir 的交互增強&#xff1a;單擊、雙擊與鼠標 Hover 功能實現 功能簡述 通過防抖&#xff0c;實現單擊雙擊區分通過mousemove事件&#xff0c;實現hover效果 實現思路 &#xff08;一&#xff09;單擊與雙擊事件 功能描述 單擊節點時&#xff0c;可以觸發…

c++-迭代器類別仿函數常用算法函數

C常用算法函數 1. 前置知識 1.1 迭代器的類別 C中&#xff0c;迭代器是 STL 容器庫的核心組件之一&#xff0c;具有舉足輕重的作用&#xff0c;它提供了一種 統一的方式來訪問和遍歷容器&#xff0c;而無需關心底層數據結構的具體實現。迭代器類似指針&#xff0c;但比指針更通…

Python深度學習框架TensorFlow與Keras的實踐探索

基礎概念與安裝配置 TensorFlow核心架構解析 TensorFlow是由Google Brain團隊開發的開源深度學習框架&#xff0c;其核心架構包含數據流圖&#xff08;Data Flow Graph&#xff09;和張量計算系統。數據流圖通過節點表示運算操作&#xff08;如卷積、激活函數&#xff09;&…

c# net6.0+ 安裝中文智能提示

https://github.com/stratosblue/IntelliSenseLocalizer 1、安裝tool dotnet tool install -g islocalizer 2、 安裝IntelliSense 文件&#xff0c;安裝其他net版本修改下版本號 安裝中文net6.0采集包 islocalizer install auto -m net6.0 -l zh-cn 安裝中英文雙語net6.0采集包…

【建模與仿真】二階鄰居節點信息驅動的節點重要性排序算法

導讀&#xff1a; 在復雜網絡中&#xff0c;挖掘重要節點對精準推薦、交通管控、謠言控制和疾病遏制等應用至關重要。為此&#xff0c;本文提出一種局部信息驅動的節點重要性排序算法Leaky Noisy Integrate-and-Fire (LNIF)。該算法通過獲取節點的二階鄰居信息計算節點重要性&…

指令微調Qwen3實現文本分類任務

參考文檔&#xff1a; SwanLab入門深度學習&#xff1a;Qwen3大模型指令微調 - 肖祥 - 博客園 vLLM&#xff1a;讓大語言模型推理更高效的新一代引擎 —— 原理詳解一_vllm 原理-CSDN博客 概述 為了實現對100個標簽的多標簽文本分類任務&#xff0c;前期調用gpt-4o進行prom…

【機器學習-3】 | 決策樹與鳶尾花分類實踐篇

0 序言 本文將深入探討決策樹算法&#xff0c;先回顧下前邊的知識&#xff0c;從其基本概念、構建過程講起&#xff0c;帶你理解信息熵、信息增益等核心要點。 接著在引入新知識點&#xff0c;介紹Scikit - learn 庫中決策樹的實現與應用&#xff0c;再通過一個具體項目的方式來…