leetcode:Median of Two Sorted Arrays分析和实现
这个问题的大意是提供两个有序的整数数组A与B,A与B并集的中间数。[1,3]与[2]的中间数为2,因为2能将A与B交集均分。而[1,3]与[2,4]的中间数为2.5,取2与3的平均值。故偶数数目的中间值与奇数数目的中间值的算法不同。这个问题要求时间复杂度不超过O(log(n+m)),其中n与m分别为A与B的长度。
对于这个问题,我一开始的想法是同时对两个集合用二分查找法,这样每次过程都能有效减少一部分的冗余数据,且这样的算法的时间复杂度为O(log(n)+log(m))=O(log(max(n,m))=O(log(n+m))。
但是在这个问题的解答区看到了一个更优的解决方案。
https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation
其优化的方案是明确了一个有用的想法。我们可以找到一个切割点i与j,将A与B做如下切分:
A[0], ..., A[i-1] | A[i], ..., A[n - 1],
B[0], ..., B[j-1] | B[j], ..., B[m - 1]
如果i'与j'能够满足下面条件,那么就能将A与B的并均分为A[0], ..., A[i'-1], B[0], ..., B[j'-1]与A[i'], ..., A[n - 1], B[j'], ..., B[m - 1],且前者中所有元素都不大于后者的任意元素。
1.i'+j' = n-i'+m-j' -> 2i+2j'=n + m (保证两个集合拥有等量数值)
2.not (i'-1>=0 and j'<m and A[i'-1]>B[j]) (保证A[0], ..., A[i'-1]中所有元素都小于B[j'], ..., B[m - 1])
3.not (j'-1>=0 and i'<n and B[j'-1]>A[i]) (保证B[0], ..., B[j'-1]中所有元素都小于A[i'], ..., A[n - 1])
上面需要对i'与j'的范围做校验是因为可能存在空集(比如当i=0时,{A[0],..., A[i-1]}表示一个空集),空集应该满足所有的比较关系,因为它不包含任何元素,我们自然可以对其所有元素做任意假定。
由条件1可以看出,可能符合条件的j可以由i唯一确定。不妨设n<m(不然可以在开始时交换二者引用),那么利用二分查找法可以保证只做log(n)次循环就可以得到正确的i与j,而每次循环只需要花费常量时间,故这样一个算法的复杂度就称为了O(log(A.length))=O(log(min(n,m))。
这里可以使用二分查找法的原因是,若存在i,j满足条件1,但是不满足条件2(或条件3),那么正确的切割i’<i(或i'>i),这是因为当i增大时,j就会相对减小,而若i'>i,会致使A[i'-1]>=A[i-1]>B[j]>=B[j'],故条件2依旧不成立,因此正确的切割i’<i(或i'>i)。
lb = 0, rb = n
while lb <= rb then
i = (lb + rb) / 2
j = (n + m) / 2 - i //条件1
if i - 1 >= 0 and j < m and A[i-1] > B[j] then //条件2
rb = i
else if j-1 >= 0 and i < n and B[j-1] > A[i] then //条件3
lb = i + 1
else
i' = i, j' = j
break
一但我们得到了i'与j',那么就可以轻易的计算中间数,中间数应该是(max(A[0], ..., A[i'-1], B[0], ..., B[j'-1])+min(A[i'], ..., A[n - 1], B[j'], ..., B[m - 1])) / 2,这条式子等价与(max(A[i'-1], B[j'-1])+min(A[i'], B[j'])) / 2。
上面只给出了当n+m为偶数时的解决方案,而对于n+m为奇数时可以将j = (n + m) / 2 - i替换为j = (n + m + 1) / 2 - i,即将中间值保存在A[0], ..., A[i'-1], B[0], ..., B[j'-1]中。最后的结果应该为max(A[i'-1], B[j'-1])。
最后给出java代码,有需要的人可以看看
package cn.dalt.leetcode; /** * Created by dalt on 2017/6/4. */public class MedianOfTwoSortedArrays2 { public static void main(String[] args) { int[] nums1 = new int[]{1}; int[] nums2 = new int[]{2, 3, 4}; System.out.println(new MedianOfTwoSortedArrays2().findMedianSortedArrays(nums1, nums2)); } public double findMedianSortedArrays(int[] nums1, int[] nums2) { if (nums1.length > nums2.length) { int[] temp = nums1; nums1 = nums2; nums2 = temp; } int len1 = nums1.length; int len2 = nums2.length; int totalLength = len1 + len2; int halfLength = totalLength >> 1; int offset = totalLength & 1; int lbound = 0; int rbound = nums1.length; while (lbound <= rbound) { int i = (lbound + rbound) >> 1; int j = ((len1 + len2 + offset) >> 1) - i; if (j < len2 && i > 0 && nums1[i - 1] > nums2[j]) { rbound = i; } else if (j > 0 && i < len1 && nums2[j - 1] > nums1[i]) { lbound = i + 1; } else { int smallmid = i <= 0 ? nums2[j - 1] : j <= 0 ? nums1[i - 1] : Math.max(nums1[i - 1], nums2[j - 1]); if (offset == 0) { int largermid = i >= len1 ? nums2[j] : j >= len2 ? nums1[i] : Math.min(nums1[i], nums2[j]); return (smallmid + largermid) / 2.0; } return smallmid; } } return -1; }}
leetcode:Median of Two Sorted Arrays分析和实现的更多相关文章
- LeetCode: Median of Two Sorted Arrays 解题报告
Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...
- [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 ...
- [leetcode]Median of Two Sorted Arrays @ Python
原题地址:https://oj.leetcode.com/problems/median-of-two-sorted-arrays/ 题意:There are two sorted arrays A ...
- Leetcode 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 ...
- LeetCode—— Median of Two Sorted Arrays
Description: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the medi ...
- Leetcode: Median of Two Sorted Arrays. java.
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...
- C++ Leetcode Median of Two Sorted Arrays
坚持每天刷一道题的小可爱还没有疯,依旧很可爱! 题目:There are two sorted arrays nums1 and nums2 of size m and n respectively. ...
- LeetCode——Median of Two Sorted Arrays
Question There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median o ...
- LeetCode Median of Two Sorted Arrays 找中位数(技巧)
题意: 给两个有序(升or降)的数组,求两个数组合并之后的中位数. 思路: 按照找第k大的思想,很巧妙.将问题的规模降低,对于每个子问题,k的规模至少减半. 考虑其中一个子问题,在两个有序数组中找第k ...
随机推荐
- CallKit iOS 教程
原文:CallKit Tutorial for iOS 作者:József Vesza 译者:kmyhy 对 VoIP App 开发者来说,iOS 的支持并不友好.尤其是它的通知发送这一块,太糙了.你 ...
- Leetcode 807. Max Increase to Keep City Skyline
class Solution(object): def maxIncreaseKeepingSkyline(self, grid): """ :type grid: Li ...
- CSS3实现多列纵向滚动
效果如图: 小程序wxml: <view class='wraper'> <view class="header"> 头部 </view> &l ...
- 瀑布流下滑 发送ajax
<!DOCTYPE=html> <html> <head> <meta charset="UTF-8"> ...
- 【PS实例】轻松打造梦幻的照片
本系列教程将开始讲解PS的一些制作实例,通过实例的讲解同时介绍各种工具和面板机快捷键的使用,这样能够让大家更有兴趣学习,在学习的同时能够创造出自己喜欢的东西.本人使用的教程都是根据本人多次调试制作,仅 ...
- innerHTML和innerText怎么区分
示例代码:<div id="test"> <span style="color:red">test1</span> test ...
- gitlab Failed to register this runner. Perhaps you are having network problems runner 注册失败问题解决
1. 低版本安装地址 https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/v1.11.2/index.html 2. 使用 yum ...
- Linux环境安装git
git配置 源码安装 检测当前git版本是否是2.7.4以上 git --version 如果没有安装git直接源码安装即可,如果安装了先删除原来的git. yum -y remove git 先安装 ...
- JAVA设计模式:静态代理
一.概念代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关 ...
- 51nod 1965 奇怪的式子 —— min_25筛
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 推式子就同这里:https://www.cnblogs.com/yoyo ...