算法題打卡力扣第4題:尋找兩個正序數組的中位數(hard))

題目描述

在這里插入圖片描述

提示:

nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106

解答思路

我的想法是先歸并排序再直接返回下標中位數
代碼

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {int i=0,j=0,k=0;int c[nums1Size+nums2Size];while(i<nums1Size&&j<nums2Size){if(nums1[i]<nums2[j])c[k++]=nums1[i++];elsec[k++]=nums2[j++];}while(i<nums1Size)c[k++]=nums1[i++];while(j<nums2Size)c[k++]=nums2[j++];if((nums1Size+nums2Size)%2==1)return c[(nums1Size+nums2Size)/2];elsereturn (c[(nums1Size+nums2Size)/2-1]+c[(nums1Size+nums2Size)/2])/2.0;
}

結果
在這里插入圖片描述
復雜度分析
時間復雜度:O(m+n)
空間復雜度:O(n+m)

解法二,二分查找法(最優解)

二分查找的算法模板from算法模板

bool check(int x){ /* ... */}//檢查x是否滿足某種性質//區間[l,r]被劃分成[l,mid] 和 [mid+1,r]時使用;
int bsearch_1(int l,int r)
{while(l<r){int mid = l+r >>1;if(check(mid)) r=mid;else l = mid + 1;}return l;
}
//區間[l,r]被劃分成[l,mid-1] 和 [mid,r]時使用:
int bsearch_2(int l,int r)
{while(l<r){int mid = l+r+1>>1;if(check(mid)) l=mid;else r=mid-1;}return l;
}

既然題目要求對數級別的時間復雜度,我們必須考慮使用二分查找。這里的難點在于,我們不是在一個簡單的數組上進行二分,而是在一個“虛擬”的合并數組上進行。

核心思想:轉化問題
尋找中位數,本質上是在尋找一個“分割點”,這個分割點能將一個集合分成左右兩個部分,且左邊部分的所有元素都小于等于右邊部分的所有元素。

對于這道題,我們要在 nums1 和 nums2 中找到兩個分割點,將兩個數組都分成左右兩部分。這兩個分割點需要滿足以下兩個條件:
長度條件:左半部分所有元素的個數之和 等于 右半部分所有元素的個數之和(或多一個,當總數為奇數時)。
大小條件:左半部分所有元素的最大值 小于等于 右半部分所有元素的最小值。
只要我們找到了滿足這兩個條件的分割點,中位數就自然而然地由分割點周圍的元素決定了

具體步驟:
為了簡化,我們假設 nums1 是長度較短的那個數組(如果不是,可以交換它們)。

  • 我們對較短的數組 nums1 進行二分查找。我們要查找的不是一個值,而是一個合適的分割線索引 i。這個 i 將 nums1 分成 nums1[0…i-1](左半部分)和 nums1[i…m-1](右半部分)。

  • 設總長度的一半為 halfLen = (m + n + 1) / 2。(這里 +1 是一個小技巧,可以同時處理奇偶情況)。

  • 一旦 nums1 的分割線 i 確定了,nums2 的分割線 j 也隨之確定,必須滿足 i + j = halfLen,所以 j = halfLen - i。j 將 nums2 分成 nums2[0…j-1] 和 nums2[j…n-1]。

  • 現在我們有了四個關鍵的邊界值
    nums1 左半部分的最大值:nums1[i-1] (設為 L1)
    nums1 右半部分的最小值:nums1[i] (設為 R1)
    nums2 左半部分的最大值:nums2[j-1] (設為 L2)
    nums2 右半部分的最小值:nums2[j] (設為 R2)

  • 接下來,我們檢查“大小條件”是否滿足。正確的分割線必須滿足:L1 <= R2 并且 L2 <= R1。
    如果 L1 > R2:說明 nums1 的分割線 i 太靠右了,nums1 左邊的數太大了。我們需要將 i 向左移動。在二分查找中,這意味著要縮小查找區間的右邊界 (high = i - 1)。
    如果 L2 > R1:說明 nums1 的分割線 i 太靠左了,nums1 右邊的數太小了(等價于 nums2 左邊的數太大了)。我們需要將 i 向右移動。在二分查找中,這意味著要擴大查找區間的左邊界 (low = i + 1)。
    如果同時滿足 L1 <= R2 和 L2 <= R1:恭喜,我們找到了完美的分割線!現在可以計算中位數了:
    如果總長度 (m+n) 是奇數:中位數就是兩個左半部分中的最大值,即 max(L1, L2)。
    如果總長度 (m+n) 是偶數:中位數是左半部分最大值和右半部分最小值的平均值,即 (max(L1, L2) + min(R1, R2)) / 2.0。

  • 處理邊界:當 i 或 j 為 0 或數組長度時,其左邊或右邊可能沒有元素。這時我們可以把 L1, L2 視為負無窮大,把 R1, R2 視為正無窮大,這樣大小比較的邏輯依然成立。

代碼實現:
不太會寫,學習一下g老師的代碼

#include <stdio.h>
#include <limits.h> // 用于 INT_MIN 和 INT_MAX// 一個簡單的宏來獲取最大值和最小值,比引入 math.h 更輕量
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {// 確保 nums1 是較短的數組,這樣可以減少二分查找的次數if (nums1Size > nums2Size) {return findMedianSortedArrays(nums2, nums2Size, nums1, nums1Size);}int m = nums1Size;int n = nums2Size;int low = 0, high = m;// 在較短的數組 nums1 上進行二分查找while (low <= high) {// partition1 是 nums1 的分割點int partition1 = low + (high - low) / 2;// partition2 是 nums2 的分割點,根據總長度的一半來計算int partition2 = (m + n + 1) / 2 - partition1;// 獲取分割線左側的最大值// 如果 partition1 為 0,說明 nums1 的左半部分為空,取負無窮int maxLeft1 = (partition1 == 0) ? INT_MIN : nums1[partition1 - 1];// 如果 partition2 為 0,說明 nums2 的左半部分為空,取負無窮int maxLeft2 = (partition2 == 0) ? INT_MIN : nums2[partition2 - 1];// 獲取分割線右側的最小值// 如果 partition1 等于 m,說明 nums1 的右半部分為空,取正無窮int minRight1 = (partition1 == m) ? INT_MAX : nums1[partition1];// 如果 partition2 等于 n,說明 nums2 的右半部分為空,取正無窮int minRight2 = (partition2 == n) ? INT_MAX : nums2[partition2];// 檢查是否找到了完美的分割線if (maxLeft1 <= minRight2 && maxLeft2 <= minRight1) {// 如果總元素個數是偶數if ((m + n) % 2 == 0) {return (MAX(maxLeft1, maxLeft2) + MIN(minRight1, minRight2)) / 2.0;} else { // 如果總元素個數是奇數return (double)MAX(maxLeft1, maxLeft2);}} // 如果 nums1 左邊的最大值大于了 nums2 右邊的最小值// 說明 partition1 太大了,需要向左移動else if (maxLeft1 > minRight2) {high = partition1 - 1;} // 否則說明 partition1 太小了,需要向右移動else {low = partition1 + 1;}}// 如果程序運行到這里,說明輸入數組不是有序的,按題目要求不會發生// 在實際工程中,這里應該拋出異常return -1.0; 
}// ------ 主函數用于測試 ------
int main() {// 測試用例 1: 奇數總長int nums1[] = {1, 3};int nums2[] = {2};double median1 = findMedianSortedArrays(nums1, 2, nums2, 1);printf("Test Case 1: Median is %f\n", median1); // 應該輸出 2.0// 測試用例 2: 偶數總長int nums3[] = {1, 2};int nums4[] = {3, 4};double median2 = findMedianSortedArrays(nums3, 2, nums4, 2);printf("Test Case 2: Median is %f\n", median2); // 應該輸出 2.5return 0;
}

運行結果:
在這里插入圖片描述

復雜度分析:
時間復雜度:O(log(min(m,n)))
空間復雜度:O(1)
ok see you next time~

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

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

相關文章

無人機抗噪模塊技術概述!

一、 技術要點1. 傳感器數據融合與濾波&#xff08;解決感知噪聲&#xff09;核心思想&#xff1a;單一傳感器易受干擾且不全面&#xff0c;通過融合多種傳感器&#xff08;IMU慣性測量單元、GPS、氣壓計、磁力計、視覺傳感器、激光雷達等&#xff09;的數據&#xff0c;利用算…

Horse3D游戲引擎研發筆記(六):在QtOpenGL環境下,仿Unity的材質管理Shader繪制四邊形

在上一篇筆記中&#xff0c;我們已經實現了基于QtOpenGL的BufferGeometry管理VAO和EBO繪制四邊形的功能。這一次&#xff0c;我們將深入探討材質管理系統的實現&#xff0c;包括Shader的加載與編譯、材質的創建與使用&#xff0c;以及如何通過材質系統繪制帶有自定義Shader效果…

MySQL-分庫分表(Mycat)

目錄 1.介紹? 概述 拆分策略 垂直拆分? 水平拆分? 實現技術? shardingJDBC: MyCat: 2.Mycat概述 環境準備? 分片配置 schema.xml? server.xml 啟動服務? 分片測試? 3.MyCat配置 schema.xml? schema標簽 datanode標簽 ?datahost標簽? rule.xml …

Dubbo 的 Java 項目間調用的完整示例

1. 項目結構假設項目分為三個模塊&#xff1a;api&#xff1a;定義服務接口provider&#xff1a;服務提供者consumer&#xff1a;服務消費者2. 依賴配置在 pom.xml 中添加 Dubbo 和注冊中心&#xff08;如 Nacos&#xff09;的依賴&#xff1a;<dependency><groupId&g…

Python進行中文分詞

1. jieba庫概述 jieba&#xff08;“結巴”&#xff09;是Python中最流行的中文分詞庫&#xff0c;采用基于前綴詞典實現的高效分詞算法&#xff0c;支持多種分詞模式&#xff0c;是中文自然語言處理(NLP)的基礎工具。 核心特性 精確模式&#xff1a;試圖將句子最精確地切開&am…

JavaScript 性能優化實戰:從原理到落地的完整指南

一、引言&#xff1a;為什么 JavaScript 性能優化至關重要&#xff1f;性能與用戶體驗的強關聯數據支撐&#xff1a;加載延遲每增加 1 秒&#xff0c;用戶轉化率下降 7%&#xff08;來自 Google 研究&#xff09;核心痛點&#xff1a;現代 Web 應用中 JS 代碼體積膨脹、運行時卡…

前端自動化部署

摘要&#xff1a;前端自動化部署是通過工具和流程自動化實現前端代碼從開發完成到線上發布的全流程&#xff0c;減少人工操作、提高效率并降低出錯風險。核心目標減少重復操作&#xff1a;自動化構建、測試、部署等步驟&#xff0c;替代手動上傳服務器等低效方式。提升發布效率…

peewee中db.create_tables(tables, safe=True),safe=True作用

db.create_tables(tables, safeTrue) 中的 safeTrue 參數的作用是 防止在表已經存在的情況下引發錯誤。 具體來說&#xff1a; 當 safeTrue 時&#xff1a;Peewee 會在生成的 SQL 語句中加入 IF NOT EXISTS 子句&#xff08;例如&#xff1a;CREATE TABLE IF NOT EXISTS my_tab…

2025年計算機視覺與圖像國際會議(ICCVI 2025)

2025年計算機視覺與圖像國際會議| 視界創新&#xff0c;圖領未來 2025年計算機視覺與圖像國際會議&#xff08;ICCVI 2025&#xff09;將在中國東莞盛大召開。這不僅是一次匯聚全球頂尖科學家、工程師和學者的盛會&#xff0c;更是一個探索計算機視覺和圖像處理領域前沿技術與未…

Temu美國站大規模掃號封店:虛假本土店遭批量封禁,如何規避?

2025年8月&#xff0c;Temu平臺針對美國站再次掀起大規模掃號風暴。大量店鋪因注冊信息違規被判定為“高風險”&#xff0c;不僅店鋪被凍結&#xff0c;商品也被下架并禁止補貨。這一輪清掃&#xff0c;讓不少依靠“資料店”快速起盤的賣家遭遇重創。事實上&#xff0c;Temu的風…

航空發動機葉片yolov8模型訓練和轉換(包含適配rk3588-pt轉onnx轉rknn)

前言&#xff1a; 1.訓練在windows進行&#xff0c;因為電腦沒有顯卡&#xff0c;所以純cpu訓練&#xff0c;生成pt后轉onnx 2.onnx轉需要在Ubuntu虛擬機上運行 3.數據集標定快捷鍵 &#xff08;模型訓練時不需要&#xff09;官方地址和下載pt權重&#xff1a;鏈接&#xff…

PyTorch如何修改模型(魔改)?/替換模型,一般除了注意輸入輸出一致,還有其他要修改的嗎?

一、PyTorch如何修改模型&#xff08;魔改&#xff09;? 可以參考這個鏈接&#xff0c;看了一下還不錯&#xff1a; PyTorch如何修改模型&#xff08;魔改&#xff09;_模型魔改-CSDN博客 二、替換模型&#xff0c;一般除了注意輸入輸出一致&#xff0c;還有其他要修改的嗎?…

Pycharm Debug詳解

Pycharm Debug詳解看這個工具欄就是 PyCharm 調試器的“步進/斷點”按鈕區。常用按鈕和作用&#xff08;從左到右一般是這些&#xff09;&#xff1a; Resume / 繼續運行&#xff08;F9&#xff09;&#xff1a;從當前斷點繼續跑&#xff0c;直到下一個斷點或程序結束。Step Ov…

將SSL配置遷移到Nacos的步驟

將SSL配置遷移到Nacos的步驟 要將SSL配置從本地application.yml遷移到Nacos配置中心&#xff0c;需要完成以下幾個步驟&#xff1a; 1. 創建Nacos配置文件 在Nacos中創建一個新的配置文件&#xff08;例如application-ssl.yml&#xff09;&#xff0c;內容如下&#xff1a; ser…

HTTP請求參數類型及對應的后端注解

在Java后端開發中&#xff0c;HTTP請求的不同部分需要使用不同的注解來處理。以下是四種主要請求參數類型及其對應的Spring注解&#xff1a;1. 請求頭(Headers)??位置??&#xff1a;HTTP請求的頭部信息??常用場景??&#xff1a;認證信息(Token)、客戶端信息、內容類型等…

服務器硬件電路設計之 SPI 問答(一):解密 SPI—— 從定義到核心特性

在服務器硬件電路設計中&#xff0c;SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外設接口&#xff09;是一種關鍵的通信總線。它由摩托羅拉公司開發&#xff0c;是全雙工、同步串行通信總線&#xff0c;主要用于微控制器與外圍設備之間的通信&#xff0c;憑借…

【2025CVPR-目標檢測方向】OW-OVD:統一的開放世界和開放詞匯對象檢測

研究背景與動機? ?問題?:傳統目標檢測器(封閉集)需預定義所有類別,無法適應動態開放環境。現有研究多獨立解決開放詞匯檢測(OVD)或開放世界檢測(OWOD),未結合兩者優勢: ?OVD?:通過文本-視覺嵌入匹配實現零樣本泛化,但無法主動發現未知對象。 ?OWOD?:可主動…

基于Python的就業信息推薦系統 Python+Django+Vue.js

本文項目編號 25011 &#xff0c;文末自助獲取源碼 \color{red}{25011&#xff0c;文末自助獲取源碼} 25011&#xff0c;文末自助獲取源碼 目錄 一、系統介紹二、系統錄屏三、啟動教程四、功能截圖五、文案資料5.1 選題背景5.2 國內外研究現狀 六、核心代碼6.1 查詢數據6.2 新…

el-date-picker type=daterange 日期范圍限制

html &#xff08;組件&#xff1a;element-ui&#xff09;重點&#xff1a; :picker-options"pickerOptions"<template><el-date-pickerv-model"form.dateRange"type"daterange" value-format"yyyy-MM-dd"range-separator&q…

【38頁PPT】關于5G智慧園區整體解決方案(附下載方式)

篇幅所限&#xff0c;本文只提供部分資料內容&#xff0c;完整資料請看下面鏈接 https://download.csdn.net/download/2501_92808811/91694207 資料解讀&#xff1a;《關于5G智慧園區整體解決方案》 詳細資料請看本解讀文章的最后內容。 智慧園區行業理解與建設目標 智慧園…