题目:

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)).

题意:

两个排序后的数组nums1 和nums2,长度分别是m,n,找出其中位数,并且时间复杂度:O(log(m+n))

最愚蠢的方法:

两个数组合并成一个,排序,取出中位数

Java程序:

public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int median_index = (m+n)/2;
int nums[] = new int[m+n];
if(m!=0)
for(int k=0;k<m;k++)
nums[k] = nums1[k];
if(n!=0)
for(int k=0;k<n;k++)
nums[m+k] = nums2[k];
Arrays.sort(nums);
if((m+n)%2==1)
return nums[median_index];
else
return (nums[median_index]+nums[median_index-1])/2.0;
}
}

无耻的又用Python实现了一遍

class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
m = len(nums1)
n = len(nums2)
median_index = (m+n)/2
nums=[num for num in nums1]
for num in nums2:
nums.append(num)
nums.sort()
if((m+n)%2==1):
return nums[median_index]
else:
return (nums[median_index]+nums[median_index-1])/2.0

说明一下:

Python中 sorted(list)排序是直接返回排序后的结果,原list没有改变,而list.sort() 不返回排序后的结果,结果更新list

正确方法:

问题转化为:nums1和nums2合并排序后的第k个元素

主要思想是:每次剔除部分对求第k个元素没有用的数据

假设nums1和nums2原始序列是升序的,则是求合并后升序的第k个元素,或者第k大元素

假设nums1和nums2原始序列是降序的,则是求合并后降序的第k个元素,或者第k小元素

下面假设是升序

m = nums1.length

n = nums2.length

若 nums1是空的,结果就是 nums2[k]

若 nums2是空的,结果就是 nums1[k]

若 k==0,返回nums1[0] 、nums2[0]中的较小者

对于其他情况:

为了好说明,定义变量:nums1Start,nums1End,nums2Start,nums2End

我们要求的是合并后的第k大的数

小于第k大的数是没有用的

对于合并排序后的前k个数,理想情况下,是均匀的分布在nums1 和nums2中

k个数中nums1中占:nums1Mid = nums1Len*k/(nums1Len+nums2Len)个  这里除法取的是下界

k个数中nums2中占:nums2Mid = k – nums1Mid – 1 个 这里是因为下标是从0开始

由于我们定义了开始位置,则:

nums1Mid = nums1Mid + nums1Start

nums2Mid = nums2Mid + nums2Start

下面比较这两个位置对应元素的大小:nums1[nums1Mid ]   nums2[nums2Mid]

若:nums1[nums1Mid ]  > nums2[nums2Mid]  说明:第k大的数在nums1中的nums1Start 到nums1Mid 之间  和 nums2 中nums2Mid 到nums2End之间

可以发现我们去除的有效部分只是nums2中的nums2Start 到 nums2Mid之间的元素,而nums1中 nums1Mid到nums1End之间的原始已经是大于 第k个元素了。

所以更新k,k = k - (nums2Mid – nums2Start + 1)

同时更新:nums1End = nums1Mid  ,nums2Start = nums2Mid + 1,其他不变

若:nums1[nums1Mid ]  < nums2[nums2Mid]  说明:第k大的数在num1中的num1Mid到nums1End之间 和 nums2中的nums2Start到nums2Mid之间

更新k,k = k - (nums1Mid – nums1Start + 1)

同时更新: nums1Start = nums1Mid + 1,nums2End = nums2Mid ,其他不变

若:nums1[nums1Mid ]  = nums2[nums2Mid]

这里正好是第k个数,就是所求答案

对于上面两种情况,继续递归求解

关于时间复杂度:在最坏的情况下,每次都要去除k/2的元素,则log(k) = log((m+n)/2) = log(m+n)

Java程序:

public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
if((m+n)%2==1)//odd
return (double)findKth(nums1,0,m-1,nums2,0,n-1,((m+n)/2));
else
return (findKth(nums1,0,m-1,nums2,0,n-1,(m+n)/2)+findKth(nums1,0,m-1,nums2,0,n-1,(m+n)/2-1))/2.0;
} public int findKth(int[] nums1,int nums1Start,int nums1End,int[] nums2,int nums2Start,int nums2End,int k){
int nums1Len = nums1End - nums1Start + 1;
int nums2Len = nums2End - nums2Start + 1;
if(nums1Len ==0)
return nums2[nums2Start+k];
if(nums2Len ==0)
return nums1[nums1Start+k];
if(k==0)
return nums1[nums1Start]<nums2[nums2Start] ? nums1[nums1Start]:nums2[nums2Start];
int nums1Mid = nums1Len*k/(nums1Len+nums2Len);
int nums2Mid = k - nums1Mid - 1 ;
nums1Mid = nums1Mid + nums1Start;
nums2Mid = nums2Mid + nums2Start;
if(nums1[nums1Mid] > nums2[nums2Mid]){
k = k - (nums2Mid - nums2Start + 1);
nums1End = nums1Mid;
nums2Start = nums2Mid + 1;
}else if(nums1[nums1Mid] < nums2[nums2Mid]){
k = k - (nums1Mid - nums1Start + 1);
nums2End = nums2Mid;
nums1Start = nums1Mid + 1;
}else
return nums1[nums1Mid];
return findKth(nums1,nums1Start,nums1End,nums2,nums2Start,nums2End,k);
} }

程序参考

对于降序的情况:

当是降序的时候,出来这个结果:

在网上找个C++程序,当是降序的时候,上面的输入也是2.0000,上面给的期望答案也是2.0000

然后我就试试这个输入

上面的C++程序和上面的Java程序都是输入6.0000

题目中没有说升序的啊,但是许多人都默认升序做了,降序输入结果就不对了。

上面的Java程序和上面C++程序原理是很类似的,但是只能对升序求解,降序数组下标需要修改,大于和小于 和上面的恰好相反

好吧,咱就当升序的数组处理。上面的都对。

既然是升序,尝试用两个变量指向两个数组的开始位置,比较大小,异步前进,发现,,,,,,,,,,,,,,,,坑太大,检测中间点的可能太多,,,,,或者定义许多boolean变量检测 ,,,,,,,,,,,不写了,,是写的不对。。。已乱。。。

又转换成Python代码:

class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
nums1Len = len(nums1)
nums2Len = len(nums2)
if (nums1Len + nums2Len)%2==1:
return 1.0*self.findKth(nums1,0,nums1Len-1,nums2,0,nums2Len-1,(nums1Len + nums2Len)/2)
return (self.findKth(nums1,0,nums1Len-1,nums2,0,nums2Len-1,(nums1Len + nums2Len)/2)+self.findKth(nums1,0,nums1Len-1,nums2,0,nums2Len-1,(nums1Len + nums2Len)/2-1))*0.5 def findKth(self,nums1,nums1Start,nums1End ,nums2,nums2Start,nums2End,k):
nums1Len = nums1End - nums1Start + 1
nums2Len = nums2End - nums2Start + 1
if nums1Len==0 : return nums2[nums2Start + k]
if nums2Len==0 : return nums1[nums1Start + k]
if k==0: return min(nums1[nums1Start],nums2[nums2Start])
nums1Mid = nums1Len*k/(nums1Len + nums2Len)
nums2Mid = k - nums1Mid - 1
nums1Mid += nums1Start
nums2Mid += nums2Start
if nums1[nums1Mid]== nums2[nums2Mid]:
return nums2[nums2Mid]
if nums1[nums1Mid] > nums2[nums2Mid]:
k = k - (nums2Mid - nums2Start + 1)
nums1End = nums1Mid
nums2Start = nums2Mid + 1
if nums1[nums1Mid] < nums2[nums2Mid]:
k = k - (nums1Mid - nums1Start + 1)
nums2End = nums2Mid
nums1Start = nums1Mid + 1
return self.findKth(nums1,nums1Start,nums1End,nums2,nums2Start,nums2End,k)

leetcode 4 : Median of Two Sorted Arrays 找出两个数组的中位数的更多相关文章

  1. LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  2. Leetcode 4. Median of Two Sorted Arrays(二分)

    4. Median of Two Sorted Arrays 题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ Descr ...

  3. 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays

    一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...

  4. LeetCode(3) || Median of Two Sorted Arrays

    LeetCode(3) || Median of Two Sorted Arrays 题记 之前做了3题,感觉难度一般,没想到突然来了这道比较难的,星期六花了一天的时间才做完,可见以前基础太差了. 题 ...

  5. LeetCode——4. Median of Two Sorted Arrays

    一.题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays 二.题目大意: 给定两个排序过的数组,求出两个数组的中位数,要求时间复 ...

  6. LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)

    题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...

  7. Leetcode 4. Median of Two Sorted Arrays(中位数+二分答案+递归)

    4. Median of Two Sorted Arrays Hard There are two sorted arrays nums1 and nums2 of size m and n resp ...

  8. LeetCode 4. Median of Two Sorted Arrays & 归并排序

    Median of Two Sorted Arrays 搜索时间复杂度的时候,看到归并排序比较适合这个题目.中位数直接取即可,所以重点是排序. 再来看看治阶段,我们需要将两个已经有序的子序列合并成一个 ...

  9. 第三周 Leetcode 4. Median of Two Sorted Arrays (HARD)

    4. Median of Two Sorted Arrays 给定两个有序的整数序列.求中位数,要求复杂度为对数级别. 通常的思路,我们二分搜索中位数,对某个序列里的某个数 我们可以在对数时间内通过二 ...

随机推荐

  1. Spring-Mybatis 异常记录(1)

    Spring  applicationconfig.xml如下 <?xml version="1.0" encoding="UTF-8"?> < ...

  2. 简单实用的PHP验证码类

    一个简单实用的php验证码类,分享出来 ,供大家参考. 代码如下: <?php /** @ php 验证码类 @ http://www.jbxue.com */ Class code { var ...

  3. PHP获取上个月、下个月、本月的日期(strtotime(),date())

    今天写程序的时候,突然发现了很早以前写的获取月份天数的函数,经典的switch版,但是获得上月天数的时候,我只是把月份-1了,估计当时太困了吧,再看到有种毛骨悚然的感觉,本来是想再处理一下的,但是一想 ...

  4. 谈网页游戏外挂之用python模拟游戏(热血三国2)登陆

    看web看多了,想写写页游的外挂,其实原理是一样的,就是端口不一样协议字段你不知道,而这也提高了点技术门槛,看我们来一点一点突破这些门槛,这次我们来用python发包模拟flash的客户端登陆. 以热 ...

  5. Windows Server 2008 R2 64bit兼容Chrome浏览器

    近日更换系统Windows Server 2008 R2 64bit系统,发现谷歌浏览器插件无法正常运行,终于找到如下解决方案: 打开桌面谷歌浏览器属性,将target目标 C:\Users\Admi ...

  6. VS编译时自动下载NuGet管理的库

    之前一直使用NuGet来管理一些第三方的库,但是每次check in代码时候为了保证编译通过,都需要把对应的packages check in. 比较耗费时间,特别是往github上同步代码,而且这些 ...

  7. SharePoint 101 Code Samples are now available

    The Microsoft Office Developer Center has created 101 code samples for SharePoint 2010. These sample ...

  8. 面试问到struts1与struts2的解析对比

    一.struts1要继承一个抽象类.struts1是类编程而不是接口编程. struts2的action可以实现一个action接口,也可以实现其他的接口,使其成为可选的定制的服务. 二.struts ...

  9. 【转】如何设置Android软键盘的默认不弹出?

    在开发Anroid的时候,当你打开一个界面的时候,屏幕的焦点会自动停留在第一个EditText中,Android的软键盘默认会自动弹出,用户第一眼连界面都没有看清楚,软键盘就弹出来了,这就影响到了用户 ...

  10. EXT--表单AJax提交后台,返回前端数据格式的转换

    前言: 前端发送请求至服务端(Java),得到的数据是Java语言对象所表现的形式,经常需要转换为JSON格式的字符串写出至前端:当前端获取后也往往需要将字符串转换为js的对象.本文描述了在EXT作为 ...