题目:

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. Winform 导出Excel

    private void 导出excelToolStripMenuItem_Click(object sender, EventArgs e) { ) { var saveFileDialog1 = ...

  2. 51nod1269 B君的圆锥

    1629 B君的圆锥 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 B君要用一个表面积为S的圆锥将白山云包起来.   B君希望包住的白山云体积尽量 ...

  3. Crusher Django 学习笔记4 使用Model

    http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial4-using-basic.html 顺便学习一下FQ Crush ...

  4. Global::validateEmail

    /***************************************************************** (C) Copyright DENTSPLY Internatio ...

  5. 十一、 BOOL类型、分支结构和关系运算符

    BOOL类型:表示非真即假.只有两个值:YES和NO,而二进制只识别二进制数,所以,将YES替换为“1”,NO替换为“0” BOOL数据类型占一字节的空间内存 BOOL数据类型输出为:%lu:输入为: ...

  6. IE8的Textarea滚动条乱跳的解决方案

    最近在弄的一个项目,其中一个页面需要输入很长的文字,因为文字是纯文本的,所以用了Textarea,在webkit下没有任何问题,结果在IE8下测试时,发现当文本超超出Textarea的大小时,在输入文 ...

  7. VBS基础篇 - 数组

    数组变量:有时需要向一个单一的变量赋于多个值,那么您可以创建一个可包含一系列值的变量,这种变量被称为数组. '静态数组 ) a()="George" a()="john& ...

  8. ios的UIImage的两种不同的图片加载方式 tom猫

    在ios的UI交互设计时,对图片的处理是难免的:不同的处理方式会对内存有不同的影响: ********************************************************* ...

  9. eclipse不能创建java虚拟机-解决方法

    找到eclipse目录下的eclipse.ini,可以看到如下内容: -startup plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar ...

  10. Discuz!NT3.6与网站整合(操作用户信息)解决方案

    因为网站要加个论坛,所以就用到了Discuz!NT3.6. 可惜目前官方论坛已经关闭,只有3.6版本的有源码,3.9的没有源码,不好操作,下载地址: http://download.comsenz.c ...