题目难度:hard

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 = [1, 3]
nums2 = [2] The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4] The median is (2 + 3)/2 = 2.5

翻译:

有两个已排序的数组nums1和nums2长度分别是m和n。

找到这两个数组的中值。整个运行时复杂度应该是O(log(m+n))。

想了老半天,

思路一:将两个数组直接放入List,然后调用Collection.sort()排好,最后返回其中位值

思路二:利用归并排序中的合并算法,将两个数组按顺序比大小拼接成一个数组(),最后返回其中位值

思路一Code:2080测试用例—107ms(beats 6.25%)  时间复杂度:O(N*logN)…………假设Collections.sort()为快速排序O(N*logN)

 public double findMedianSortedArrays(int[] nums1, int[] nums2) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < nums1.length; i++) {
list.add(nums1[i]);
}
for (int i = 0; i < nums2.length; i++) {
list.add(nums2[i]);
}
Collections.sort(list);
if ( list.size() % 2 == 0) {
return (list.get(list.size()/2) + list.get(list.size()/2 - 1))/2.0;
} else {
return list.get(list.size()/2);
}
}

用了Collection自带的sort方法,省得自己写排序代码。。。呃,有种作弊的感脚

总体速度貌似也还行,就是显得蠢了点=。=根本没用到“已排序”这个条件

【最近发现java.util.Arrays类直接就有Arrays.sort(int[] a)方法。。。】

思路二Code:2080测试用例—66ms(beats 70.29%)  时间复杂度:O(N+M)…………最小为O(N)

     public static double findMedianSortedArrays2(int[] A, int[] B) {
int[] uniArray = uniSort(A, B);
if (uniArray.length % 2 == 0) {
return (uniArray[uniArray.length / 2] + uniArray[uniArray.length / 2 - 1]) / 2.0;
} else {
return uniArray[uniArray.length / 2];
}
} private static int[] uniSort(int[] A, int[] B) {
int[] result = new int[A.length + B.length];
int i = 0,j = 0;
int k = 0; while (i < A.length && j < B.length) {
if (A[i] < B[j]) {
result[k++] = A[i++];
} else {
result[k++] = B[j++];
}
}
while (i < A.length) {
result[k++] = A[i++];
}
while (j < B.length) {
result[k++] = B[j++];
}
return result;
}

这种方法应该是最容易想到的了,没啥技巧性可言,就是用一个辅助数组和一个int k 作为指针进行移动

代码可读性不错,时间复杂度也可观。

好吧,还是显得蠢了点。。。

参考答案(选了个可读性好点的)

思想:采用二分法,不考虑数值大小,只管查找当前下标是否在需要定位的下标的一半内

Code:2080测试用例—86ms(beats 21.34%)  时间复杂度:O(log(m + n))

     public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
// 处理无效边界
if (nums1 == null || nums2 == null) return 0.0; int m = nums1.length, n = nums2.length;
if ((m + n) % 2 !=0) {
// 如果 m + n 长度是奇数,返回中间那一个
return getKth(nums1, 0, nums2, 0, (m + n + 1) / 2);
} else {
// 如果 m + n 长度是偶数,两个函数将返回一个左数和一个右数
return (getKth(nums1, 0, nums2, 0, (m + n + 1) / 2) + getKth(nums1, 0, nums2, 0, (m + n + 2) / 2)) / 2.0;
}
} private static double getKth(int[] nums1, int start1, int[] nums2, int start2, int k) {
// 这个函数旨在nums1+nums2中找到第k个元素[而不是下标为k,这两个数组并没有合并不存在统一下标] // 如果nums1耗尽,则返回nums2中的kth号
if (start1 > nums1.length - 1) return nums2[start2 + k - 1]; // 如果nums2耗尽,则返回nums1中的第k号
if (start2 > nums2.length - 1) return nums1[start1 + k - 1]; // 如果k==1,返回第一个数字
// 因为nums1和nums2是排序的,所以nums1和nums2的起始点中的较小的一个是第一个
if (k == 1) return Math.min(nums1[start1], nums2[start2]); int mid1 = Integer.MAX_VALUE;
int mid2 = Integer.MAX_VALUE;
// 为什么不取0,因为当某一边长度不够折半时,它的mid默认长度应该比任何能折半的mid都大(保证让对方折半)
if (start1 + k / 2 - 1 < nums1.length) mid1 = nums1[start1 + k / 2 - 1];
if (start2 + k / 2 - 1 < nums2.length) mid2 = nums2[start2 + k / 2 - 1]; // 将数组中的一半从nums1或nums2中删除。把k切成两半
if (mid1 < mid2) {
return getKth(nums1, start1 + k / 2, nums2, start2, k - k / 2); //nums1.right + nums2
} else {
return getKth(nums1, start1, nums2, start2 + k / 2, k - k / 2); //nums1 + nums2.right
}
}

看了老半天才勉强看懂,比较难理解,不过时间复杂度小。

下面举个例子方便理解:

A【。。。】数组

B【。。。】数组

很假设中位数下标为k

下面以这俩数组为例,介绍这个“二分法求俩已排序数组中位数”

1. k =( n + m +1) / 2   // 假设m+n是奇数

2. 假设合并后的数组为C【。。。】,现在将C平均分成4部分,所以可以分为

  C【0,k/2-1】;// k/2-1前半段的中位数的下标

  C【略1】

  C【略2】

  C【略3】

3. 现在假如A内可以数到下标 k/2-1 = 1,B也可以数到。

  所以C的k点的值必然大于  A数组k/2  与  B数组k/2  这两点中小的那一个点!所以小的那一个点对应的数组从起点到此点都不可能出现k,所以可以删去。

  所以比较  A数组k/2  与  B数组k/2  ,将小的那个数组从start到k/2截去(将起点设置为start+k/2-1),然后继续递归搜索。

总结:如果真的出了这种题目,笔试就写第二种吧,复杂度也差不太多。面试的话先说第二种,再说第三种。

ps:LeetCode中写注释貌似会影响最后的成绩。

LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD的更多相关文章

  1. 2.Median of Two Sorted Arrays (两个排序数组的中位数)

    要求:Median of Two Sorted Arrays (求两个排序数组的中位数) 分析:1. 两个数组含有的数字总数为偶数或奇数两种情况.2. 有数组可能为空. 解决方法: 1.排序法 时间复 ...

  2. Leetcode4.Median of Two Sorted Arrays两个排序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 nums2 不同 ...

  3. leetcode第四题:Median of Two Sorted Arrays (java)

    Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...

  4. [LintCode] Median of Two Sorted Arrays 两个有序数组的中位数

    There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

  5. 【LeetCode每天一题】Median of Two Sorted Arrays(两数组中的中位数)

    There are two sorted arrays nums1 and nums2 of size m and n respectively.  Find the median of the tw ...

  6. [LeetCode] 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 ...

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

  8. 004 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 ...

  9. 4. Median of Two Sorted Arrays(2个有序数组的中位数)

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

随机推荐

  1. 使用Dell R710 IDRAC挂载虚拟介质

    Dell DRAC,虚拟介质分离或所选虚拟磁盘驱动器的虚拟介质重定向已由另一用户使用 DELL Idrac 一台Dell的R710服务器,远程管理器后发现虚拟介质无法映射,一直提示“虚拟介质分离或所选 ...

  2. CURLOPT_SSL_VERIFYPEER CURLOPT_SSL_VERIFYHOST

    w /** * Set curl options relating to SSL. Protected to allow overriding. * @param $ch curl handle */ ...

  3. jd算法大赛 一个user_id只需映射到一个sku_id, 但是一个sku_id能否映射到多个user_id

    0-购买预测 w 任务目标 提交user_id-->sku_id (1->1,但反向呢?) 实际操作: 0- 行为表中的type值加权为一个购买意向值0(性别.年龄,不干扰/或加权) 品类 ...

  4. 流畅的python 闭包

    闭包 人们有时会把闭包和匿名函数弄混.这是有历史原因的:在函数内部定义函数不常见,直到开始使用匿名函数才会这样做.而且,只有涉及嵌套函数时才有闭包问题.因此,很多人是同时知道这两个概念的.其实,闭包指 ...

  5. (转)RTP-H264封包分析

    rtp(H264)第一个包(单一NAL单元模式)————-sps 80 {V=10,p=0,x=0,cc=0000} 60 {m=0,pt=110 0000} 53 70{sequence numbe ...

  6. s5_day9作业

    # 1 编写 tail -f a.txt |grep 'error' |grep '404'命令,周一默写 # import time # def tail(filepath,encoding='ut ...

  7. 75. Sort Colors(荷兰国旗问题 三指针)

      Given an array with n objects colored red, white or blue, sort them so that objects of the same co ...

  8. 与进程相关的命令ps、kill

    一.概述 Ubuntu中主要有如下操作进程的命令 二.进程查看命令 ps 2.1 ps –l PPID:父进程的 PID PID:进程的PID S:进程状态,S:是指sleep睡眠状态:T:是挂起状态 ...

  9. POJ_2533 Longest Ordered Subsequence【DP】【最长上升子序列】

    POJ_2533 Longest Ordered Subsequence[DP][最长递增子序列] Longest Ordered Subsequence Time Limit: 2000MS Mem ...

  10. $python数据分析基础——初识matplotlib库

    基本用法 import numpy as np import matplotlib.pyplot as plt # 年份 year = [1950,1970,1990,2010] # 全球总人口(单位 ...