博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
4. 两个排序数组的中位数
阅读量:4027 次
发布时间:2019-05-24

本文共 2233 字,大约阅读时间需要 7 分钟。

有两个大小为 m 和 n 的排序数组 nums1 和 nums2 

请找出两个排序数组的中位数并且总的运行时间复杂度为 O(log (m+n)) 。

示例 1:

nums1 = [1, 3]nums2 = [2]中位数是 2.0

示例 2:

nums1 = [1, 2]nums2 = [3, 4]中位数是 (2 + 3)/2 = 2.5

这个讲得很好了。

思路:对长度较短的数组进行二分查找,时间复杂度为O(log(min(m,n))).

假设A为较短数组(如果A为较长数组,先对两个数组进行swap),长度为m,B为较长数组,长度为n。

将A、B分别划分成左右两部分:

对于A,划分点的位置可以有m+1种选择;对于B,划分点的位置可以有n+1种选择。

只需要保证:

(1)A[i-1]<=B[j] && B[j-1]<=A[i]

(2)i+j=m-i+n-j (m+n为偶数),或者i+j=m-i+n-j+1(m+n为奇数)即可。即j=(n+m+1)/2-i 

因此当m+n为偶数时,中位数为(max(A[i-1], B[j-1])+min(A[i], B[j]))/2,当m+n为奇数时,中位数为max(A[i-1], B[j-1])。

二分过程中,若A[i-1]>B[j],则i左移动,继续查找。若B[j-1]>A[i],则i右移动,继续查找。

 

着重介绍一下怎么处理边界:

1、需要满足条件:B[j-1] <= A[i] and A[i-1] <= B[j]

2、某些边界情况下,i=0/i=m/j=0/j=n,有些不存在了。这个时候只需要满足存在的即可。

3、所以需要满足条件: (j == 0 or i == m or B[j-1] <= A[i]) and (i == 0 or j == n or A[i-1] <= B[j])

两两组合一共九种情况,排除掉一些不可能的情况,这个时候只剩下5小类:

(1)i == 0 && B[j-1]<=A[i]

(2)j == n && B[j-1]<=A[i] 

(3)i == m && A[i-1]<=B[j] 

(4)j == 0 && A[i-1]<=B[j]

(5)B[j-1] <= A[i] and A[i-1] <= B[j]

再对5类进行逐步分析,只剩下8种情况,11诚不欺我!具体如下图:

class Solution {public:    double findMedianSortedArrays(vector
& A, vector
& B) { int m = min(A.size(), B.size()), n = max(A.size(), B.size()), i, j, l = 0, r = m; if (A.size() > B.size()){ swap(A, B); } if (A.empty()) return n % 2 == 0 ? (B[n / 2 - 1] + B[n / 2]) / 2.0 : B[n / 2]; while (l <= r) { i = (l + r) / 2; j = (m + n + 1) / 2 - i; if (i != 0 && j != n && A[i - 1] > B[j]){ r = i - 1; } else if (j != 0 && i != m && B[j - 1] > A[i]){ l = i+1; } else{ //找到i if (i == 0 && B[j - 1] <= A[i]){ if(m==n) return (A[i]+B[j-1])/2.0; else return (m+n)%2==0 ? (B[j-1]+min(A[i], B[j]))/2.0 :B[j-1]; } if (i ==m && A[i - 1] <= B[j]){ if(m==n) return (A[i-1]+B[j])/2.0; else return (m+n)%2==0 ? (max(B[j-1],A[i-1]) + B[j])/2.0 :max(A[i-1], B[j-1]); } else{ return (m+n)%2==0 ? (max(A[i-1], B[j-1])+min(A[i], B[j]))/2.0 : max(A[i-1], B[j-1]) ; } } } return 0; }};

 

转载地址:http://whabi.baihongyu.com/

你可能感兴趣的文章
Ubuntu+win10远程桌面
查看>>
flutter-实现圆角带边框的view(android无效)
查看>>
flutter-实现一个下拉刷新上拉加载的列表
查看>>
android 代码实现圆角
查看>>
postman调试webservice接口
查看>>
flutter-解析json
查看>>
android中shader的使用
查看>>
java LinkedList与ArrayList迭代器遍历和for遍历对比
查看>>
Android DataBinding使用2-Recycleview
查看>>
drat中构造方法
查看>>
JavaScript的一些基础-数据类型
查看>>
JavaScript基础知识(2)
查看>>
转载一个webview开车指南以及实际项目中的使用
查看>>
关于activity保存页面状态的两个方法
查看>>
android中对于非属性动画的整理
查看>>
一个简单的TabLayout的使用
查看>>
关于let{a}=B出现的解构赋值
查看>>
ReactNative使用Redux例子
查看>>
Promise的基本使用
查看>>
android给文字加边框(修改不能居中的问题)
查看>>