leetcode-4. 寻找两个正序数组的中位数。

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/two-sum

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一: 辅助数组对原来的两数组进行归并。
double findMedianSortedArrays( int *nums1, int nums1Size, int *nums2, int nums2Size ) {
	double answer = 0.0;
	int i1 = 0, i2 = 0, ti = 0, *tempArray = NULL;

	tempArray = malloc( sizeof(*tempArray) * (nums1Size + nums2Size) );

	while( i1 < nums1Size && i2 < nums2Size ) {
		tempArray[ti++] = nums1[i1] <= nums2[i2] ? nums1[i1++] : nums2[i2++];
	}
	while( i1 < nums1Size ) {
		tempArray[ti++] = nums1[i1++];
	}
	while( i2 < nums2Size ) {
		tempArray[ti++] = nums2[i2++];
	}

	answer = (ti & 1) ? tempArray[ti / 2] * 2 : tempArray[ti / 2] + tempArray[ti / 2 - 1];

	free( tempArray );

	return answer / 2.0;
}
解法二:模拟归并过程。

其实并不需要将两数组合并, 只需要找到中位数在位置即可.

double findMedianSortedArrays( int *nums1, int nums1Size, int *nums2, int nums2Size ) {
	int lasttime = 0, current = 0, len = nums1Size + nums2Size;
	int half = len / 2;

	for( int i1 = 0, i2 = 0, i = 0; i <= half; ++i ) {
		lasttime = current; // 记录中位数上一次的位置的值.
		if( i2 >= nums2Size || (i1 < nums1Size && nums1[i1] <= nums2[i2]) ) {
			current = nums1[i1++];
		} else if( i2 < nums2Size ) {
			current = nums2[i2++];
		}
	}

	return len & 1 ? current : (lasttime + current) / 2.0;
}
解法三:求中位数其实就是求第 k 小数的一种特殊情况。

前面解法的遍历过程中每次只去掉一个不可能是中位数的元素,
由于数列是有序的,其实完全可以一半一半的排除,
假设要找第 k 小的元素, 遍历过程中每次排除掉 k/2 个元素.
参考:
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/

#define MIN( a, b ) ((a) <= (b) ? (a) : (b))

static int recursion( int a[], int aSize, int b[], int bSize, int k ) {
	int kc2 = k / 2;
	int ai = MIN( aSize, kc2 ) - 1, bi = MIN( bSize, kc2 ) - 1;

	if( aSize < 1 || bSize < 1 ) {
		return aSize < 1 ? b[k - 1] : a[k - 1];
	}
	if( k < 2 ) {
		return MIN( a[0], b[0] );
	}
	if( a[ai] <= b[bi] ) {
		return recursion( a + MIN( aSize, ai + 1 ), aSize - (ai + 1), b, bSize, k - (ai + 1) );
	}

	return recursion( a, aSize, b + MIN( bSize, bi + 1 ), bSize - (bi + 1), k - (bi + 1) );
}

double findMedianSortedArrays( int *nums1, int nums1Size, int *nums2, int nums2Size ) {
	int len = nums1Size + nums2Size;
	double answer = 0.0;

	// 假设数组共有7个元素, 则:
	// 中位数 = (第4个元素 + 第4个元素) / 2.0.
	// 中位数 = (第(8/2)个元素 + 第(9/2)个元素) / 2.0.

	// 假设数组共有8个元素, 则:
	// 中位数 = (第4个元素 + 第5个元素) / 2.0.
	// 中位数 = (第(9/2)个元素 + 第(10/2)个元素) / 2.0.

	// 数组的元素数量不管是奇数还是偶数,
	// 中位数都为 (第((len+1)/2)个元素 + 第((len+2)/2)个元素) / 2.0.

	answer += recursion( nums1, nums1Size, nums2, nums2Size, (len + 1) / 2 );
	answer += recursion( nums1, nums1Size, nums2, nums2Size, (len + 2) / 2 );

	return answer / 2.0;
}

leetcode-4. 寻找两个正序数组的中位数的更多相关文章

  1. 微软面试题: LeetCode 4. 寻找两个正序数组的中位数 hard 出现次数:3

    题目描述: 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的中位数. 进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决 ...

  2. [LeetCode]4.寻找两个正序数组的中位数(Java)

    原题地址: median-of-two-sorted-arrays 题目描述: 示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1, ...

  3. leetcode 刷题(数组篇)4题 寻找两个正序数组的中位数(二分查找)

    题目描述 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 示例 1: 输入:nums1 = [1,3], nums2 = ...

  4. Leetcode随缘刷题之寻找两个正序数组的中位数

    我一上来没读清题,想着这题这么简单,直接就上手写了: package leetcode.day_12_05; import java.util.ArrayList; import java.util. ...

  5. leetcode 4. Median of Two Sorted Arrays 寻找两个正序数组的中位数(困难)

    一.题目大意 标签: 查找 https://leetcode.cn/problems/median-of-two-sorted-arrays 给定两个大小分别为 m 和 n 的正序(从小到大)数组 n ...

  6. 【LeetCode】4. Median of Two Sorted Arrays 寻找两个正序数组的中位数

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:数组,中位数,题解,leetcode, 力扣,python ...

  7. Leetcode4. 寻找两个正序数组的中位数

    > 简洁易懂讲清原理,讲不清你来打我~ 输入两个递增数组,输出中位数![在这里插入图片描述](https://img-blog.csdnimg.cn/25550994642144228e9862 ...

  8. LeetCode-004-寻找两个正序数组的中位数

    寻找两个正序数组的中位数 题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 示例说明请见LeetCode官网. ...

  9. 寻找两个已序数组中的第k大元素

    寻找两个已序数组中的第k大元素 1.问题描述 给定两个数组与,其大小分别为.,假定它们都是已按照增序排序的数组,我们用尽可能快的方法去求两个数组合并后第大的元素,其中,.例如,对于数组,.我们记第大的 ...

随机推荐

  1. Gradle系列之Groovy基础篇

    原文发于微信公众号 jzman-blog,欢迎关注交流. 上一篇学习了 Gradle 的入门知识,Gradle 基于 Groovy,今天学习一下 Groovy 的基础知识,Groovy 是基于 JVM ...

  2. 资料整理:python接口类

    1开发原则(七大原则) 一:开放封闭原则 二:接口隔离原则(将不同接口对象一一展现出来,分别调用各自的接口,完成各自的功能) 三:依赖倒置原则 高级模块不能依赖低级模块,可以依赖抽象 规范的定义: 高 ...

  3. 机器学习5- 对数几率回归+Python实现

    目录 1. 对数几率回归 1.1 求解 ω 和 b 2. 对数几率回归进行垃圾邮件分类 2.1 垃圾邮件分类 2.2 模型评估 混淆举证 精度 交叉验证精度 准确率召回率 F1 度量 ROC AUC ...

  4. 三步教你如何在Github部署自己的简历

    相信铁子们有很多都是将找工作的小白(和小编一样!!嘿嘿)小编也和在座的大家一样,一个普通的不能再普通的二本学生(北华大学) <  单身!单身!单身!> 听很多人都说:像我们这个样子,害!放 ...

  5. php获取远程文件内容的函数

    一个简单的php获取远程文件内容的函数代码,兼容性强.直接调用就可以轻松获取远程文件的内容,使用这个函数也可获取图片.代码如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  6. 2019-2020-1 20199326《Linux内核原理与分析》第五周作业

    第五周学习内容 庖丁解牛Linux内核分析第四章:系统调用的三层机制(上) Linux内核分析实验四 学到的一些知识 4.1用户态.内核态.中断 宏观上Linux操作系统的体系架构分为用户态和内核态 ...

  7. MySQL系列(三)

    本章内容: 视图.增/删/改/查 触发器.增/删/改/查 存储过程.增/删/改/查 存储过程三种传参,pymysql 怎么用? 函数.增/删/改/查/return值 内置函数 事务 1.1视图 视图是 ...

  8. 从GC的SuppressFinalize方法带你深刻认识Finalize底层运行机制

    如果你经常看开源项目的源码,你会发现很多Dispose方法中都有这么一句代码: GC.SuppressFinalize(this); ,看过一两次可能无所谓,看多了就来了兴趣,这篇就跟大家聊一聊. 一 ...

  9. 鸟哥Linux私房菜(基础篇)——第五章:首次登入与在线求助 man page笔记

    1.X Winsows与文本模式的切换 ●[Ctrl] + [Alt] + [F1] ~ [F6] :文字接口登入 tty1 ~ tty6 终端机.        ●[Ctrl] + [Alt] + ...

  10. 标准库模块time,datetime

    在Python中,通常有这几种方式来表示时间: 1)时间戳 2)格式化的时间字符串 3)元组(struct_time)共九个元素. 由于Python的time模块实现主要调用C库,所以各个平台可能有所 ...