leetcode 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)).
题意:
两个排序后的数组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 找出两个数组的中位数的更多相关文章
- 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 ...
- Leetcode 4. Median of Two Sorted Arrays(二分)
4. Median of Two Sorted Arrays 题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ Descr ...
- 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...
- LeetCode(3) || Median of Two Sorted Arrays
LeetCode(3) || Median of Two Sorted Arrays 题记 之前做了3题,感觉难度一般,没想到突然来了这道比较难的,星期六花了一天的时间才做完,可见以前基础太差了. 题 ...
- LeetCode——4. Median of Two Sorted Arrays
一.题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays 二.题目大意: 给定两个排序过的数组,求出两个数组的中位数,要求时间复 ...
- LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)
题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...
- 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 ...
- LeetCode 4. Median of Two Sorted Arrays & 归并排序
Median of Two Sorted Arrays 搜索时间复杂度的时候,看到归并排序比较适合这个题目.中位数直接取即可,所以重点是排序. 再来看看治阶段,我们需要将两个已经有序的子序列合并成一个 ...
- 第三周 Leetcode 4. Median of Two Sorted Arrays (HARD)
4. Median of Two Sorted Arrays 给定两个有序的整数序列.求中位数,要求复杂度为对数级别. 通常的思路,我们二分搜索中位数,对某个序列里的某个数 我们可以在对数时间内通过二 ...
随机推荐
- Winform 导出Excel
private void 导出excelToolStripMenuItem_Click(object sender, EventArgs e) { ) { var saveFileDialog1 = ...
- 51nod1269 B君的圆锥
1629 B君的圆锥 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 B君要用一个表面积为S的圆锥将白山云包起来. B君希望包住的白山云体积尽量 ...
- Crusher Django 学习笔记4 使用Model
http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial4-using-basic.html 顺便学习一下FQ Crush ...
- Global::validateEmail
/***************************************************************** (C) Copyright DENTSPLY Internatio ...
- 十一、 BOOL类型、分支结构和关系运算符
BOOL类型:表示非真即假.只有两个值:YES和NO,而二进制只识别二进制数,所以,将YES替换为“1”,NO替换为“0” BOOL数据类型占一字节的空间内存 BOOL数据类型输出为:%lu:输入为: ...
- IE8的Textarea滚动条乱跳的解决方案
最近在弄的一个项目,其中一个页面需要输入很长的文字,因为文字是纯文本的,所以用了Textarea,在webkit下没有任何问题,结果在IE8下测试时,发现当文本超超出Textarea的大小时,在输入文 ...
- VBS基础篇 - 数组
数组变量:有时需要向一个单一的变量赋于多个值,那么您可以创建一个可包含一系列值的变量,这种变量被称为数组. '静态数组 ) a()="George" a()="john& ...
- ios的UIImage的两种不同的图片加载方式 tom猫
在ios的UI交互设计时,对图片的处理是难免的:不同的处理方式会对内存有不同的影响: ********************************************************* ...
- eclipse不能创建java虚拟机-解决方法
找到eclipse目录下的eclipse.ini,可以看到如下内容: -startup plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar ...
- Discuz!NT3.6与网站整合(操作用户信息)解决方案
因为网站要加个论坛,所以就用到了Discuz!NT3.6. 可惜目前官方论坛已经关闭,只有3.6版本的有源码,3.9的没有源码,不好操作,下载地址: http://download.comsenz.c ...