题目:

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. asp.net mvc常用的数据注解和验证以及entity framework数据映射

    终于有时间整理一下asp.net mvc 和 entity framework 方面的素材了. 闲话少说,步入正题: 下面是model层的管理员信息表,也是大伙比较常用到的,看看下面的代码大伙应该不会 ...

  2. SignalR 2.0 系列: 开始使用SignalR 2.0

    这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第四篇:开始使用SignalR 2.0 原文:Getting S ...

  3. Func 委托

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. PHP获取和操作配置文件php.ini的几个函数

    当无法修改php.ini配置文件怎么办,莫担心. php有一套设置和获取配置信息的函数. 1.ini_get()获取配置参数,ini_set()设置配置参数 <?php

  5. PHP 登录完成后如何跳转上一访问页面

    访问网站页面时,有的页面需要授权才能访问,这时候就会要求用户登录,跳转到登录页面login.php,怎么实现登录后返回到刚才访问的页面 项目需求 访问网站页面时,有的页面需要授权才能访问,这时候就会要 ...

  6. JMS消息头

    一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...

  7. .Net码农学Android---前言

    自从毕业参加工作后,就一直想学移动领域得开发,但时间.精力.决心.学习成本等这些问题总在不同程度的阻碍着自己. 但这段时间自己想做一款属于自己的App的想法越来越强烈,我感到自己快压不住这股能量了.终 ...

  8. SQLserver关于教学楼中教室在某个时间段是否被占用的数据库设计

    需求:关于教学楼中教室在周几某个时间段是否被占用的数据库设计 具体代码如下: -------------------教学楼维度 CREATE TABLE TeacBuild ( tbID int no ...

  9. swift UIAlertController教程

    在iOS8中,UIAlertView与UIActionSheet都已经退休,取而代之的是UIAlertController!它的使用示范如下://弹出一个警告框,标题是“提示”,信息是“我的博客:oa ...

  10. 游刃于MVC、WCF中的Autofac

    为了程序的健壮性.扩展性.可维护性,依赖抽象而不是具体实现类等等,于是我选择了Autofac依赖注入容器 就是这个工厂来降低耦合.之前买东西是自己去超市,现在呢 我需要什么东西,他们给送过来直接拿到了 ...