力扣经典 4. 寻找两个正序数组的中位数(多种语言解)

        给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。

目录

题目描述

知识点

解题思路

完整代码

Python

Java

C


题目描述

给定两个大小分别为 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

提示:

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -10^6 <= nums1[i], nums2[i] <= 10^6

 

知识点

  1. 中位数的定义:一个集合的中位数将集合划分为两个等长的子集,其中一个子集的元素总是大于另一个子集的元素。
  2. 二分查找:由于数组是有序的,并且要求算法的时间复杂度为O(log(m+n)),我们需要使用二分查找技术来达到这个要求。
  3. 分治算法:通过将大问题分解为小问题来解决的一种算法策略。
  4. 数组操作:如索引访问、长度计算等基本操作。

解题思路

        要达到O(log(m+n))的时间复杂度,直接合并两个数组后找中位数的方法(时间复杂度为O(m+n))不可取。我们需要用到二分查找和分治的思想,关键是找到一个切分点,将两个数组分别切分为左右两部分,使得左边的元素总是小于右边的元素,并且左右两边的元素总数相等(或者只差一个元素,当总元素个数为奇数时)。

  1. 将较短的数组作为二分查找的对象,这样可以缩小查找范围,设较短的数组为A,较长的数组为B。
  2. 在A中设定一个切点i,在B中自动确定切点j,使得i+j等于两数组长度之和的一半(或一半多一,当总元素个数为奇数时)。
  3. 调整i的位置,使得A[i-1] <= B[j]B[j-1] <= A[i],此时左边的元素总是小于右边的元素。
  4. 根据左右两部分的长度关系确定中位数:如果总长度是奇数,中位数是左边最大的数;如果总长度是偶数,中位数是左边最大的数和右边最小的数的平均值。

完整代码

Python

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        A, B = nums1, nums2
        total = len(nums1) + len(nums2)
        half = total // 2
        
        if len(B) < len(A):
            A, B = B, A  # 保证A是较短的数组
        
        l, r = 0, len(A) - 1
        while True:
            i = (l + r) // 2  # A的切点
            j = half - i - 2  # B的切点
            
            Aleft = A[i] if i >= 0 else float("-infinity")
            Aright = A[i + 1] if (i + 1) < len(A) else float("infinity")
            Bleft = B[j] if j >= 0 else float("-infinity")
            Bright = B[j + 1] if (j + 1) < len(B) else float("infinity")
            
            # 分割正确
            if Aleft <= Bright and Bleft <= Aright:
                if total % 2:
                    return min(Aright, Bright)
                return (max(Aleft, Bleft) + min(Aright, Bright)) / 2
            elif Aleft > Bright:
                r = i - 1
            else:
                l = i + 1

Java

class Solution {
   public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    if (nums1.length > nums2.length) {
        int[] temp = nums1; nums1 = nums2; nums2 = temp;  // 保证nums1是较短的数组
    }
    int m = nums1.length, n = nums2.length;
    int totalLeft = (m + n + 1) / 2;
    int l = 0, r = m;
    while (l < r) {
        int i = l + (r - l + 1) / 2;
        int j = totalLeft - i;
        if (nums1[i - 1] > nums2[j]) {
            r = i - 1;
        } else {
            l = i;
        }
    }
    int i = l, j = totalLeft - l;
    int nums1LeftMax = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];
    int nums1RightMin = i == m ? Integer.MAX_VALUE : nums1[i];
    int nums2LeftMax = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];
    int nums2RightMin = j == n ? Integer.MAX_VALUE : nums2[j];
    if (((m + n) % 2) == 1) {
        return Math.max(nums1LeftMax, nums2LeftMax);
    } else {
        return (Math.max(nums1LeftMax, nums2LeftMax) + Math.min(nums1RightMin, nums2RightMin)) / 2.0;
    }
}

}

C

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
    if (nums1Size > nums2Size) {  // 保证nums1是较短的数组
        int* temp = nums1; nums1 = nums2; nums2 = temp;
        int tmp = nums1Size; nums1Size = nums2Size; nums2Size = tmp;
    }
    int iMin = 0, iMax = nums1Size, halfLen = (nums1Size + nums2Size + 1) / 2;
    while (iMin <= iMax) {
        int i = (iMin + iMax) / 2;
        int j = halfLen - i;
        if (i < iMax && nums2[j-1] > nums1[i]){
            iMin = i + 1;  // i is too small
        } else if (i > iMin && nums1[i-1] > nums2[j]) {
            iMax = i - 1;  // i is too big
        } else {  // i is perfect
            int maxLeft = 0;
            if (i == 0) { maxLeft = nums2[j-1]; }
            else if (j == 0) { maxLeft = nums1[i-1]; }
            else { maxLeft = fmax(nums1[i-1], nums2[j-1]); }
            if ((nums1Size + nums2Size) % 2 == 1) { return maxLeft; }

            int minRight = 0;
            if (i == nums1Size) { minRight = nums2[j]; }
            else if (j == nums2Size) { minRight = nums1[i]; }
            else { minRight = fmin(nums2[j], nums1[i]); }

            return (maxLeft + minRight) / 2.0;
        }
    }
    return 0.0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/436434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kakarot:当今以太坊的未来

1. 引言 前序博客&#xff1a; Kakarot&#xff1a;部署在Starknet上的ZK-EVM type 3 随着 Kakarot zkEVM 即将发布测试网&#xff0c;想重申下 Kakarot zkEVM 的愿景为&#xff1a; 为什么在rollup空间中还需要另一个 zkEVM&#xff1f; 开源代码见&#xff1a; https:/…

Python与FPGA——局部二值化

文章目录 前言一、局部二值化二、Python局部二值化三、FPGA局部二值化总结 前言 局部二值化较全局二值化难&#xff0c;我们将在此实现Python与FPGA的局部二值化处理。 一、局部二值化 局部二值化就是使用一个窗口&#xff0c;在图像上进行扫描&#xff0c;每扫出9个像素求平均…

Android耗电分析之Battery Historian工具使用

Battery-Historian是谷歌推出的一款专门分析Bugreport的工具&#xff0c;是谷歌在2015年I/O大会上推出的一款检测运行在android5.0(Lollipop)及以后版本的设备上电池的相关信息和事件的工具&#xff0c;是一款对于分析手机状态&#xff0c;历史运行情况很好的可视化分析工具。 …

基于单片机的电子秤设计

目 录 摘 要 I Abstract II 引 言 1 1 系统总体设计方案 4 1.1 设计目标与要求 5 1.2 方案论证与选择 6 2 硬件电路设计 7 2.1 单片机型号选择 7 2.2 显示模块电路设计 8 2.3 传感器模块电路设计 9 2.4 按键模块电路设计 11 2.5 报警模块电路设计 12 2.6 模数转换电路设计 12 …

Java | 一维数组的声明与使用

一维数组的声明 Java中声明数组的方法&#xff1a; <变量类型>[] <变量名>;示例&#xff1a; int[] a;上述代码中a是一个数组&#xff0c;可以保存int类型的值。 注意方括号在变量类型与名称之间。 声明数组后&#xff0c;必须为数组分配内存。内存将定义数组可…

C switch 语句

一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case&#xff0c;且被测试的变量会对每个 switch case 进行检查。 语法 C 语言中 switch 语句的语法&#xff1a; switch(expression){case constant-expression :statement(s);break; /* 可选的 */ca…

【CSP试题回顾】201703-1-分蛋糕

CSP-201703-1-分蛋糕 解题代码 #include <iostream> using namespace std;int n, k, sumCake, cake, friendNum;int main() {cin >> n >> k;for (int i 0; i < n; i){cin >> cake;sumCake cake;if (sumCake > k || i n - 1) {friendNum;sum…

【C++庖丁解牛】模版初阶

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1. 泛型编程2. 函数模…

BurpSuite2024.2.1

1.更新介绍 此版本引入了特定的API 扫描功能&#xff0c;并将 Bambdas 合并到 Logger 捕获过滤器中。我们还改进了 DOM Invader 和 Burp Suite 导航记录器的功能&#xff0c;并进行了许多其他改进和错误修复。 API扫描 我们引入了特定的 API 扫描功能。您现在可以上传 OpenAP…

DR模式下LVS负载均衡聚集部署实验

1、实验准备 DR 服务器&#xff1a;192.168.80.9Web 服务器1&#xff1a;192.168.80.11 Web 服务器2&#xff1a;192.168.80.12 nfs 服务器&#xff1a; 192.168.80.10 客户端&#xff1a;192.168.80.100 vip&#xff1a;192.168.80.188 2、配置负载调度器&#xff08;ens33&am…

ICVQUANTUMCHINA报告:《2024全球量子精密测量产业发展展望》

3月4日&#xff0c;《2024量子精密测量产业发展展望》的中文版报告通过光子盒官方平台发布&#xff0c;英文版报告通过ICV官方平台发布。 中文版报告获取地址&#xff1a;量子精密测量-QuantumChina 英文版获取地址&#xff1a;https://www.icvtank.com/newsinfo/899889.html …

DevExpress报表-->更换数据库连接

今天遇到了一个问题&#xff0c;因公司更换IP地址&#xff0c;原先连接报表数据库的IP地址也因此更改。但是&#xff0c;我不知道如何直接修改连接报表的数据。为了解决这个问题&#xff0c;我决定给大家演示一下具体的操作步骤。 换句话说: 将DevExpress报表直接从一个电脑的…

【翻译】零信任架构准则(五)Don‘t trust any network

将监控重点放在用户&#xff0c;设备和服务上 全面监控必不可少&#xff0c;因为设备和服务更容易受到网络攻击。在零信任架构中&#xff0c;随着设备&#xff0c;服务和用户行为的持续评估&#xff0c;我们的监控策略很可能发生改变。我们应该持续进行监控&#xff0c;并将用…

AMDGPU KFD Test 编译使用

ROCT-Thunk-Interface是一个用于在ROCm软件堆栈中提供设备无关性的层。它是ROCm的一部分&#xff0c;允许不同的硬件平台&#xff08;如AMD GPU和Intel CPU&#xff09;使用相同的API进行计算。 要安装ROCT-Thunk-Interface&#xff0c;首先需要创建一个新的目录&#xff0c;并…

Android视角看鸿蒙第三课(module.json中的各字段含义之nametype)

Android视角看鸿蒙第三课(module.json中的各字段含义) 前言 上篇文章我们试图找到鸿蒙app的程序入口&#xff0c;确定了在鸿蒙工程中,由AppScope下的app.json5负责应用程序的图标及名称,由entry->src->main-module.json5负责桌面图标及名称的展示。 AppScope下的app.js…

2.26-3.6

2.26 下面是项目vue脚手架 下面是node环境文件夹 2.27 npm config get prefix npm config set prefix "D:\software\nodejs"得到下面 创建脚手架 npm i vue/cli -g在项目脚手架里 vue create vue-project-1where npx vue使用vue cli创建前端工程 https://reg…

无编制教师和有编制教师区别在哪

走进教育的世界&#xff0c;我们常常听到“编制教师”与“非编制教师”的说法&#xff0c;这两者之间的区别&#xff0c;犹如一道隐形的鸿沟&#xff0c;隔开了两种不同的教育生涯。今天&#xff0c;就让我们一起来探讨一下&#xff0c;这两者之间的差异究竟体现在哪里。 教育系…

【学习资源】对比说明三个通过作者查找文献数据库(一)

最近博主在阅读相关文献的时候&#xff0c;想针对一些作者的科研文献做一个详细的了解&#xff0c;于是涉及到“如何已知作者与其所在单位&#xff0c;查找其研究成果”的问题&#xff0c;博主尝试了在Google Scholar、Web of Science、CRS核心论文库这三个地方通过作者查找文献…

Jmeter之Ramp-up Period(in seconds)

1、Ramp-up Period概念 &#xff08;in seconds&#xff09;–并发用户启动周期&#xff0c;告知JMeter 要在多长时间内启动全部Vuser用户。 2、为什么需要有“ramp-up period”&#xff0c;立即启动所有的并发用户数不是更好&#xff1f; 对于绝大多数的网址或应用&#xf…

vulhub中ThinkPHP5 SQL注入漏洞 敏感信息泄露

漏洞原理 传入的某参数在绑定编译指令的时候又没有安全处理&#xff0c;预编译的时候导致SQL异常报错。然而thinkphp5默认开启debug模式&#xff0c;在漏洞环境下构造错误的SQL语法会泄漏数据库账户和密码 启动后&#xff0c;访问http://your-ip/index.php?ids[]1&ids[]2…