递归训练1:在两个长度相等的排序数组中找到上中位数

题目要求:

 解题思路:

1. 当数组长度为偶数时,它们各自的中位数下标为:mid1=(n-1)/2;  mid2=(n-1)/2;

 当arr1[mid1] < arr2[mid2]时,目标中位数一定在arr1[mid1+1,,,,,,n]和 arr2[0,,,,,mid2]之间,不可能在其余区间;因为目标中位数的下标为n-1, 假如arr2[0,,,,mid-1]所有数全部小于arr1[mid1], 将这些小于数全部放到arr1[mid1]之后,目标中位数的最小的下标也在mid1+1处。

2. 当数组长度为奇数时,各自中位数下标与上面相同;

当arr1[mid1] < arr2[mid2]时,目标中位数在一定arr1[mid1,,,,,,n]和 arr2[0,,,,,mid2]之间,不可能在其余区间;

偶数奇数区间的区别,是由于取各自中位数时,偶数要少一位,奇数在中间。

3. 当arr1[mid1] < arr2[mid2]时,两个数组相反即可。

 代码如下:

 1 public static int getUpMedian(int[] arr1, int[] arr2) 
 2 {
 3     if (arr1==NULL || arr1==NULL)
 4     {
 5         return  -1;
 6     }
 7     find(arr1, 0, arr1.length-1, arr2, 0, arr2.length-1);
 8 }
 9 
10 void find(int[] arr1, int L1, int R1, int[] arr2, int L2, int R2)
11 {
12     int mid1=(n-1)/2;  
13     int mid2=(n-1)/2;
14     int offset = (R1-L1+1)&1;
15     if (arr1[mid1] < arr2[mid2])
16     {
17         find(arr1, mid1+offset, R1, arr2, L2, mid2);
18     }
19     else if (arr1[mid1] > arr2[mid2])
20     {
21         find(arr1, L1, mid1, arr2, mid2+offset, R2);
22     }
23     else
24     {
25         return arr1[mid1];
26         //return arr2[mid2];
27     }
28 }

迭代更简单些:

// 迭代版本
public int getUpMedian2(int[] arr1, int[] arr2) 
{   
if (arr1 == null || arr2 == null)
  {     
return -1;   }   int l1 = 0;   int r1 = arr1.length - 1;   int l2 = 0;   int r2 = arr2.length - 1;   int mid1 = 0;   int mid2 = 0;   int offset = 0;   while (l1 < r1)
  {     mid1
= l1 + (r1 - l1) / 2;     mid2 = l2 + (r2 - l2) / 2;     offset = ((r1 - l1 + 1) & 1)^1;     if (arr1[mid1] < arr2[mid2])
    {       l1
= mid1 + offset;       r2 = mid2;     }
    else if (arr1[mid1] > arr2[mid2])
    {       r1
= mid1;       l2 = mid2 + offset;     }
    else
    {       
return arr1[mid1];     }   }   return Math.min(arr1[l1], arr2[l2]);
};
原文地址:https://www.cnblogs.com/Tavi/p/12516616.html