LeetCode Problem:两个有序数组的中位数huabian - 乐橙lc8

LeetCode Problem:两个有序数组的中位数huabian

2019-02-14 07:44:56 | 作者: 念波 | 标签: 数组,中位数,元素 | 浏览: 6505

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 arrays. The overall run time complexity should be O(log (m+n)).

这个标题对错常有名的面试题,

留意leetcode上面临中位数的界说是:

假如兼并之后的数组元素个数是奇数,那么中位数就是中心的那位

假如兼并之后的数组元素个数是奇数,那么中位数是中心两位的平均数

解题思路有三种

解法一:

运用兼并排序,将两个数组从头排序成一个新的数组,这样在O(1)的时刻能够找到中位数,排序的时刻是O(n+m)

 

解法二:

先假定数组A的长度为m,数组B的长度为n

1. 先别离找出数组A和数组B的中位数 ma 和 mb,设A[i] = ma , B[j] = mb 然后比较巨细

2. 假如 ma mb, 即A[i] B[j], 那么中位数一定在A[i..m] 和 B[1..j] 之间, 然后再这个区间再求中位数,递归查找

3. 假如 ma mb, 即A[i] B[j],那么中位数一定在A[1..i] 和 B[j..n] 之间,然后再这个区间再求中位数,递归查找

 

算法比较好了解,可是程序有两点需求留意:

1) 递归的base条件是,当其间一个数组元素个数只剩余小于等于2时,递归完毕

2) 每次递归时,在两个数组中挑选除掉的元素一定要持平。比如说A数组减去两个元素,那么B数组也要减去两个,这样剩余的区间的中位数和本来的中位数是相同的

 

程序如下: 这个代码过了leetcode的一切case,算是bug free了。

/**
 * find median of two sorted array, the values in array may same
 * p 
 * The algorithm are:
 * /p 
 * ol 
 * li Calculate the medians m1 and m2 of the input arrays A and B
 * respectively. /li 
 * li If m1 is less than m2, then the median located between
 * A[m-index(m1)..m] and B[0..index(m2)], index(m1),index(m2) are the index
 * of array A and B,repeat finding median recrusively /li 
 * li If m1 is greater than m2, then the median located between
 * A[0..index(m1)] and B[n-index(m2)..n] ,repeat finding median recrusively /li 
 * /ol 
 static class FindMedian1 {
 public static double medianSelect(int[] A, int[] B) {
 if (A  null B  null) {
 return -1;
 } else if ((A  null || A.length  0) B.length != 0) {
 return B.length % 2  1 ? B[(B.length - 1) / 2]
 : (B[(B.length - 1) / 2] + B[(B.length - 1) / 2 + 1]) / 2.0;
 } else if (B  null || B.length  0 A.length != 0) {
 return A.length % 2  1 ? A[(A.length - 1) / 2]
 : (A[(A.length - 1) / 2] + A[(A.length - 1) / 2 + 1]) / 2.0;
 return findMedian(A, 0, A.length - 1, B, 0, B.length - 1);
 public static double findMedian(int[] A, int p, int r, int[] B, int l,
 int h) {
 if (p  r) {// only one element left to compare
 return findMedianBaseCase1(A[p], B, l, h);
 } else if (l  h) {
 return findMedianBaseCase1(B[l], A, p, r);
 } else if (r  p + 1) {
 return findMedianBaseCase2(A[p], A[r], B, l, h);
 } else if (h  l + 1) {
 return findMedianBaseCase2(B[l], B[h], A, p, r);
 int medA = (p + r) / 2;
 int medB = (l + h) / 2;
 if (A[medA] = B[medB]) {
 int k = 0;
 if ((r - p + 1) % 2  0) {
 k = Math.min(medA - 1, h - medB - 1);
 } else {
 k = Math.min(medA, h - medB - 1);
 k = k  0 ? 1 : k;
 return findMedian(A, p + k, r, B, l, h - k);
 } else {
 int k = 0;
 if ((h - l + 1) % 2  0) {
 k = Math.min(medB - 1, r - medA - 1);
 } else {
 k = Math.min(medB, r - medA - 1);
 k = k  0 ? 1 : k;
 return findMedian(A, p, r - k, B, l + k, h);
 public static double findMedianBaseCase1(int med, int[] A, int p, int r) {
 if (r  p) {
 return (med + A[p]) / 2.0;
 if (med  A[(r + p) / 2]) {
 return med;
 } else if (med A[(r + p) / 2]) {
 if ((r - p + 1) % 2  0) {
 return A[(r + p) / 2];
 } else {
 return (Math.max(med, A[(r + p) / 2 - 1]) + A[(r + p) / 2]) / 2.0;
 } else {// if(med A[(r+p)/2])
 if ((r - p + 1) % 2  1) {
 return (A[(r + p) / 2] + Math.min(med, A[(r + p) / 2 + 1])) / 2.0;
 } else {
 return med A[(r + p) / 2 + 1] ? med : A[(r + p) / 2 + 1];
 // med2 med1 by default
 public static double findMedianBaseCase2(int med1, int med2, int[] A,
 int p, int r) {
 int medA = (r + p) / 2;
 if (r  p + 1) {
 if (med1 A[p]) {
 if (med2 A[r]) {
 return (med1 + med2) / 2.0;
 } else {
 return (med1 + A[r]) / 2.0;
 } else if (med2 A[r]) {
 return (A[r] + A[p]) / 2.0;
 } else {
 return (med2 + A[p]) / 2.0;
 if ((r - p + 1) % 2  0) {
 if (med2 A[medA]) {
 return (Math.max(med2, A[medA - 1]) + A[medA]) / 2.0;
 } else if (med1 A[medA]) {
 if (med2 A[medA + 1]) {
 return (med1 + med2) / 2.0;
 } else {// med2 A[medA+1]
 return (Math.min(med1, A[medA + 2]) + A[medA + 1]) / 2.0;
 } else {
 return (A[medA] + Math.min(med2, A[medA + 1])) / 2.0;
 } else {
 if (med1 A[medA]) {
 return Math.min(A[medA + 1], med1);
 } else if (med2 A[medA]) {
 return Math.max(med2, A[medA - 1]);
 } else {
 return A[medA];
 }

 

 

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表乐橙lc8立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章