Median of Two Sorted Arrays

来源:互联网 发布:淘宝商家服务社区 编辑:程序博客网 时间:2024/06/16 02:28

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


大概意思就是两个排序好的数组,如果两个数组合并的话找到其中的中位置数

这是我实现的代码有点复杂
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {int len1 = nums1.length;int len2 = nums2.length;int sum = len1 + len2;int median = sum >> 1;int[] numsTemp = null;int[] numsTempOr = null;int len = 0;boolean lastgt = false;boolean lastlt = false;if (sum % 2 == 0) { // 偶数的时候int index2 = len2 >> 1;int index = 0;numsTemp = nums2;numsTempOr = nums1;len = len1;int medianSub1 = median - 1;for (;;) {if(numsTemp.length > 0 && index2 < numsTemp.length && index2 > -1)index = binarySearch(numsTempOr, numsTemp[index2], len, median - index2);else {numsTemp = nums1;numsTempOr = nums2;index2 = len1 >> 1;len = len2;continue;}if (index + index2 == median) {int index0 = index - 1;if(index2 == 0)return (numsTemp[index2] + numsTempOr[index0]) / 2.0;index = binarySearch(numsTempOr, numsTemp[index2 - 1], len, median - index2);if (index + index2 - 1 == medianSub1) {return (numsTemp[index2] + numsTemp[index2 - 1]) / 2.0;} else {return (numsTemp[index2] + numsTempOr[index0]) / 2.0;}} else if (index + index2 == medianSub1) {int index0 = index;if(index2 + 1 == numsTemp.length)return (numsTemp[index2] + numsTempOr[index]) / 2.0;index = binarySearch(numsTempOr, numsTemp[index2 + 1], len, medianSub1 - index2);if (index + index2 + 1 == median) {return (numsTemp[index2] + numsTemp[index2 + 1]) / 2.0;} else {return (numsTemp[index2] + numsTempOr[index0]) / 2.0;}} else if (index + index2 > median) {if (lastlt == true) {numsTemp = nums1;numsTempOr = nums2;index2 = len1 >> 1;len = len2;lastlt = false;} else {index2--;lastgt = true;}} else {if (lastgt == true) {numsTemp = nums1;numsTempOr = nums2;index2 = len1 >> 1;len = len2;lastgt = false;} else {index2++;lastlt = true;}}}} else { // 奇数的时候int index2 = len2 >> 1;int index = 0;numsTemp = nums2;numsTempOr = nums1;len = len1;for (;;) {if(numsTemp.length > 0 && index2 < numsTemp.length && index2 > -1)index = binarySearch(numsTempOr, numsTemp[index2], len, median - index2);else {numsTemp = nums1;numsTempOr = nums2;index2 = len1 >> 1;len = len2;continue;}if (index + index2 == median) {return numsTemp[index2];} else if (index + index2 > median) {if (lastlt == true) {numsTemp = nums1;numsTempOr = nums2;index2 = len1 >> 1;len = len2;lastlt = false;} else {index2--;lastgt = true;}} else {if (lastgt == true) {numsTemp = nums1;numsTempOr = nums2;index2 = len1 >> 1;len = len2;lastgt = false;} else {index2++;lastlt = true;}}}}}public static int binarySearch(int[] nums, int target, int size, int margin) { // 这个数在数组中前面有多少int begin = 0, end = size;int temp = 0;if(nums.length < 1) {return begin;}for (;;) {temp = (begin + end) >> 1;if (end > begin) {if (target > nums[temp]) {begin = temp + 1;} else if (target == nums[temp]) {if(temp == margin) return margin;while(nums[temp++] == target) {if(temp - 1 == margin) return margin; if(temp == size) {temp ++; break;}}; return --temp;} else {end = temp;}} else {return begin;}}}
这是官方的代码
public static double findMedianSortedArrays2(int[] A, int[] B) {        int m = A.length;        int n = B.length;        if (m > n) { // to ensure m<=n            int[] temp = A; A = B; B = temp;            int tmp = m; m = n; n = tmp;        }        //A是小数组        int iMin = 0, iMax = m, halfLen = (m + n + 1) >> 1;        while (iMin <= iMax) {            int i = (iMin + iMax) >> 1;            int j = halfLen - i;            if (i < iMax && B[j-1] > A[i]){                iMin++; // i is too small, j--, i++            } else if (i > iMin && B[j] < A[i-1]) {                iMax--; // i is too big, j++, i--            } else { // i is perfect                int maxLeft = 0;                if (i == 0) { maxLeft = B[j-1]; }                else if (j == 0) { maxLeft = A[i-1]; }                else { maxLeft = Math.max(A[i-1], B[j-1]); }                if ( (m + n) % 2 == 1 ) { return maxLeft; }                int minRight = 0;                if (i == m) { minRight = B[j]; }                else if (j == n) { minRight = A[i]; }                else { minRight = Math.min(B[j], A[i]); }                return (maxLeft + minRight) / 2.0;            }        }        return 0.0;    }
官方的逻辑是这样的:

首先将A数组随机位置i处分成两部分

First let's cut \text{A}A into two parts at a random position ii:

          left_A             |        right_A    A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]


因为A有m个元素,所以有m+1中分组方式(0~m)

已知:

Since \text{A}A has mm elements, so there are m+1m+1 kinds of cutting (i = 0 \sim mi=0m).

And we know:

\text{len}(\text{left\_A}) = i, \text{len}(\text{right\_A}) = m - ilen(left_A)=i,len(right_A)=mi.


注意:当i=0时,left_A部分是空数组; i=m时,right_A部分是空数组;

Note: when i = 0i=0\text{left\_A}left_A is empty, and when i = mi=m\text{right\_A}right_A is empty.

同理,将B在right_A随机位置j处分成两部分

With the same way, cut \text{B}B into two parts at a random position jj:

          left_B             |        right_B    B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

将left_A和left_B放入一个区域,同时将right_A和right_B放入另一个区域.并且将这两个区域命名为left_part 和 right_part

Put \text{left\_A}left_A and \text{left\_B}left_B into one set, and put \text{right\_A}right_A and \text{right\_B}right_B into another set. Let's name them \text{left\_part}left_partand \text{right\_part}right_part:

          left_part          |        right_part    A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]    B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

当要满足下面两个条件时

If we can ensure:

  1. \text{len}(\text{left\_part}) = \text{len}(\text{right\_part})len(left_part)=len(right_part)
  2. \max(\text{left\_part}) \leq \min(\text{right\_part})max(left_part)min(right_part)

我们将{A, B}两个数组里面所有的元素分成两个相同大小区域时,一个区域的值总是大于另一区域的值,推出

then we divide all elements in \{\text{A}, \text{B}\}{A,B} into two parts with equal length, and one part is always greater than the other. Then

\text{median} = \frac{\text{max}(\text{left}\_\text{part}) + \text{min}(\text{right}\_\text{part})}{2}median=2max(left_part)+min(right_part)

满足这两个条件,只需要满足这两个条件即可:

To ensure these two conditions, we just need to ensure:

  1. i + j = m - i + n - ji+j=mi+nj (or: m - i + n - j + 1mi+nj+1)
    if n \geq mnm, we just need to set:  i=0m, j=m+n+12i i=0∼m, j=m+n+12−i

  2. \text{B}[j-1] \leq \text{A}[i]B[j1]A[i] and \text{A}[i-1] \leq \text{B}[j]A[i1]B[j]

学习了

right_A
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 加热风机 涂装风机 凉水塔风机 管道式风机 风机报价 风机多少钱 循环风机 收尘风机 屋面风机 矿山风机 壁挂式风机 内蒙古风机 上海风机 直流风机 排烟通风机 75kw引风机 建准风机 小型排风机 大棚风机 中压风机 排风机型号 大棚放风机 排湿风机 温室风机 风机软连接 进口风机 隧道用风机 碎纸风机 压风机 壁式风机 引风机厂家 大型排风机 风机的型号 冷却风机 地下室风机 风机基础 屋面排风机 太原风机 增压风机 煤气风机 小风机