LeetCode-4MedianofTwoSortedArrays(C#)
# 题目
4. Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [, ] nums2 = [] The median is 2.0
Example 2:
nums1 = [, ] nums2 = [, ] The median + )/ = 2.5
# 思路
两指针填充数组法:
想法来源于插入排序的过程。插入排序每一次将一位数字之前插入有序数组之中。
例如{1, 3, 4, 2},前面三位已用插入排序排序完毕,第四位2首先和1比较,大于,再和后面一位比较,小于,故放入该位置,其余元素后移。
此题的算法:
首先,把指针index1指向nums1,指针Index2指向nums2,同时创建一个数组sum,用来保存两个数组按照大小合并的结果。
接着,比较index1和index2所指元素的大小,sum数组填充两者较小的一个,同时指向较小元素的指针后移一位。
反复上面一步,当sum填充到中间时,结束,根据奇偶,计算中间值。
举个例子:
比如nums1 = {1, 3},nums2 = {2, 4, 5},index1指向nums1中的1,index2指向nums2中的2,1 < 2,所以sum填充1。
此时index1后移指向3,3 > 2,sum填充2,index2后移。此时index2指向4,4 > 3,sum填充3。此时sum已经填充到中部,故直接输出3。
// use two pointers to construct full nums including nums1 and nums2
// two pointers: time O(m+n) space O(n) result: 255ms
public double FindMedianSortedArrays(int[] nums1, int[] nums2)
{
int[] sum;
// nums1 is null or num2 is null
if (nums1.Length == 0) sum = nums2;
else if (nums2.Length == 0) sum = nums1;
else sum = new int[nums1.Length + nums2.Length];
// user 2 pointers to find middle numbers
int length = nums1.Length + nums2.Length, index1 = 0, index2 = 0, index = 0;
for (; index < sum.Length && index1 < nums1.Length && index2 < nums2.Length; index++)
{
if (nums1[index1] < nums2[index2]) sum[index] = nums1[index1++];
else sum[index] = nums2[index2++];
}
for (; index1 < nums1.Length; index++, index1++)
sum[index] = nums1[index1];
for (; index2 < nums2.Length; index++, index2++)
sum[index] = nums2[index2];
if (length % 2 != 0) return sum[length / 2];
else return (double)(sum[length / 2 - 1] + sum[length / 2]) / 2;
}
两指针填充数组法,时间复杂度O(m + n),空间复杂度O(n),时间255ms。
算法虽然AC(Accept)了,可并不满足题中所给的时间复杂度O(lg(m + n))。谈到lg,即以2为底的对数,很容易联想到对半的思想,二分查找法。
然而我并想不出来如何二分。
去LeetCode的Discuss区看了一下。发现了这样一个算法:二分查找,划分两数组法。参考地址:https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation/90。
天才。
只说说大概流程,具体内容直接参考链接,不懂请大胆留言。
算法的主要目的是将nums1和nums2形式意义上合并,再划分成两个规模相等且右侧所有数字大于左侧所有数字的数组(利用指针标记划分的位置),再根据划分的位置(由于两部分规模相等,必然是中间元素),输出结果。
如下图,我们先确定划分位置,这个划分位置一定会将左右两侧等分。

之后我们要保证左侧所有元素小于右侧所有元素,由于nums1和nums2是有序数组,边界元素就是划分之中最大/最小的元素,所以我们只需要关注边界即可。
假设nums1划分的位置是i,nums2划分的位置是j,要满足左侧元素小于右侧所有元素,必须满足nums1[i - 1] < nums1[i](数组有序,必定满足),nums1[i - 1] < nums2[j],nums1[i] > nums2[j - 1],nums2[j - 1] < nums2[j](数组有序,必定满足)。
若不满足nums1[i - 1] < nums2[j],如图,重新确定划分位置(图只是重划分的位置只是减少了1,实际上重划分的位置采用二分法)。

若不满足nums1[i] > nums2[j - 1],如图,重新确定划分位置(图只是重划分的位置只是减少了1,实际上重划分的位置采用二分法)。

反复上述过程,最后我们可以得到中间值。

# 解决(二分查找,划分两数组法)
// reference: https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation/
// time: O(lg(min(nums1,nums2)) space: O(1) result: 228ms
public double FindMedianSortedArrays(int[] nums1, int[] nums2)
{
&& nums2.Length == ) throw new Exception("none value in nums1 and nums2");
&& nums2.Length % == ) - ] + nums2[nums2.Length / ]) / ;
&& nums2.Length % != ) ];
&& nums1.Length % == ) - ] + nums1[nums1.Length / ]) / ;
&& nums1.Length % != ) ];
if (nums1.Length > nums2.Length) return FindMedianSortedArrays(nums2, nums1);
, imax = nums1.Length, midLength = (nums1.Length + nums2.Length + ) / ;
int i, j;
// when i isn't the split must satisfy below condition
do
{
i = (imin + imax) / ;
j = midLength - i;
&& j < nums2.Length && nums1[i - ] > nums2[j]) imax--; // nums[i - 1] > nums[j] means imin is too samll
&& nums1[i] < nums2[j - ]) imin++; // nums1[i] < nums2[j - 1] means imax is small
else break;
}
while (true);
// i is split, so we get answer by conditon
// get left first
int left;
) left = nums2[j - ];
) left = nums1[i - ];
] > nums2[j - ] ? nums1[i - ] : left = nums2[j - ];
// sum length is odd
!= )
{
return (double)left;
}
else
{
int right;
if (i == nums1.Length) right = nums2[j];
else if (j == nums2.Length) right = nums1[i];
else right = nums1[i] < nums2[j] ? nums1[i] : nums2[j];
;
}
}
二分查找,划分两数组法,时间复杂度O(lg(m + n)),空间复杂度O(1),时间228ms。
# 题外话
图够丑吗?来喷我啊,嘿嘿?
# 测试用例
static void Main(string[] args)
{
_4MedianofTwoSortedArrays solution = new _4MedianofTwoSortedArrays();
Debug.Assert(solution.FindMedianSortedArrays(, }, }) == 2.0d, "wrong 1"); // odd
Debug.Assert(solution.FindMedianSortedArrays( }, , }) == 2.0d, "wrong 2"); // odd
Debug.Assert(solution.FindMedianSortedArrays(, }, , }) == 2.0d, "wrong 3"); // even and duplication
Debug.Assert(solution.FindMedianSortedArrays(, }, , }) == 2.5d, "wrong 4"); // even
Debug.Assert(solution.FindMedianSortedArrays(, }) == 3.5d, "wrong 5"); // nums1 null
Debug.Assert(solution.FindMedianSortedArrays(, }, new int[] { }) == 2d, "wrong 6"); // nums2 numm
Debug.Assert(solution.FindMedianSortedArrays(, , , , , }, }) == 4d, "wrong 7"); // only nums1 pointer move
Debug.Assert(solution.FindMedianSortedArrays( }, , , , , , , }) == 4.5d, "wrong 8"); // only nums2 pointer move
Debug.Assert(solution.FindMedianSortedArrays(, , }, , , , , }) == 3.5d, "wrong 9");
Debug.Assert(solution.FindMedianSortedArrays(, }, , , , , }) == 3d, "wrong 10");
}
# 地址
Q: https://leetcode.com/problems/median-of-two-sorted-arrays/
A: https://github.com/mofadeyunduo/LeetCode/tree/master/4MedianofTwoSortedArrays
(希望各位多多支持本人刚刚建立的GitHub和博客,谢谢,有问题可以邮件609092186@qq.com或者留言,我尽快回复)
LeetCode-4MedianofTwoSortedArrays(C#)的更多相关文章
- 我为什么要写LeetCode的博客?
# 增强学习成果 有一个研究成果,在学习中传授他人知识和讨论是最高效的做法,而看书则是最低效的做法(具体研究成果没找到地址).我写LeetCode博客主要目的是增强学习成果.当然,我也想出名,然而不知 ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
- [LeetCode] Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子字符串
Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...
- Leetcode 笔记 113 - Path Sum II
题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- Leetcode 笔记 101 - Symmetric Tree
题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...
随机推荐
- [APUE]UNIX进程的环境(下)
一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函 ...
- Hello Web API系列教程——Web API与国际化
软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化习俗,在创建不同语言版本时,不需要重新设计源程序代码的软件工程方法.这在很多成熟的软件开发平台中非常常见.对于.net开发 ...
- Java初始化过程
这篇文章主要讲解Java在创建对象的时候,初始化的顺序.主要从以下几个例子中讲解: 继承关系中初始化顺序 初始化块与构造器的顺序 已经加载过的类的初始化顺序 加载父类,会不会加载子类 创建子类对象会不 ...
- Java数据库连接技术——JDBC
大家好,今天我们学习了Java如何连接数据库.之前学过.net语言的数据库操作,感觉就是一通百通,大同小异. JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力. JDBC API ...
- UITextView 输入字数限制
本文介绍了UITextView对中英文还有iOS自带表情输入的字数限制,由于中文输入会有联想导致字数限制不准确所以苦恼好久,所以参考一些大神的博客终于搞定,欢迎大家参考和指正. 对于限制UITextV ...
- Ajax 概念 分析 举例
Ajax是结合了访问数据库,数据访问,Jquery 可以做页面局部刷新或者说是页面不刷新,我可以让页面不刷新,仅仅是数据的刷新,没有频繁的刷页面,是现在比较常用的一种方式做页面那么它是怎么实现页面无刷 ...
- 前端学HTTP之内容协商
前面的话 一个URL常常需要代表若干不同的资源.例如那种需要以多种语言提供其内容的网站站点.如果某个站点有说法语的和说英语的两种用户,它可能想用这两种语言提供网站站点信息.理想情况下,服务器应当向英语 ...
- jQuery学习之路(7)- 用原生JavaScript实现jQuery的某些简单功能
▓▓▓▓▓▓ 大致介绍 学习了妙味,用原生的JavaScript实现jQuery中的某些部分功能 定义自己的函数库lQuery ▓▓▓▓▓▓ $()选择器的实现 jQuery是面向对象的,所以自己编写 ...
- MVC通过路由实现URL重写
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Ro ...
- 用javascript 写个函数返回一个页面里共使用了多少种HTML 标签
今天我无意间看到一个面试题: 如何用javascript 写个函数返回一个页面里共使用了多少种HTML 标签? 不知你看到 是否蒙B了,如果是我 面试,肯定脑子嗡嗡的响.... 网上搜了搜也没有找到答 ...