题目地址:
https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f?tab=answerKey
题目描述
给定两个有序数组arr1和arr2,已知两个数组的长度都为N,求两个数组中所有数的上中位数。
上中位数:假设递增序列长度为n,若n为奇数,则上中位数为第n/2+1个数;否则为第n/2个数
[要求]
时间复杂度为O(logN),额外空间复杂度为O(1)O(1)
这题简单点的思路,其实就是一个双指针,
1.index1,指向数组arr1,index2指向数组arr2,
2.arr1[index1]>arr2[index2],index2++,否则 index1++
3.然后直到index1+index2 等于数组的长度,输出最后移动的指针指向的数字即可
代码实现如下:
public int findMedianinTwoSortedAray(int[] arr1, int[] arr2) {
int index1 = 0;
int index2 = 0;
int length = arr1.length;
while (index1+index2<length-1){
if (arr1[index1]<arr2[index2]){
index1++;
}else {
index2++;
}
}
return Math.min(arr1[index1],arr2[index2]);
}
但是这个算法的时间复杂度达到了O(n),不符合题目要求。所以,基本上,一般看到要求时间复杂度为O(logN),基本上能做的就是二分法了,
1.取两个数组的中间位置,mid1,mid2
2.如果 arr1[mid1] == arr2[mid2],则得到结果 返回arr1[mid1]即可,
3.arr1[mid1]>arr2[mid2],
数组arr1中mid1位置以后的数都不可能是整体的上中位数,数组arr2中mid2位置以前的数都不可能是整体的上中位数。所以现在只需要考虑arr1[left1…mid1]、arr2[mid2…right],这两部分的元素个数相同,它们的上中位数就是整体的上中位数。
然后分一下数组长度的奇偶情况,
3.1同样arr1[mid1]>arr2[mid2],
如果当前数组长度是偶数,只需要 留下 arr1 :[left1,mid1] arr2(mid2,right2]
如果当前数组长度是奇数,只需要 留下 arr1 :[left1,mid1] arr2[mid2,right2]
在这种情况下,可以看到 arr2 的右边因为数组长度分奇偶,而导致了开合。这样做是为了保证arr1 剩余长度等于 arr2 剩余长度。
4.如果arr1[mid1]<arr2[mid2]
如果当前数组长度是偶数,只需要 留下 arr1 :(mid1,right1] arr2[left2,mid2]
如果当前数组长度是奇数,只需要 留下 arr1 :[left1,mid1] arr2[mid2,right2]
示意图如下
实现代码如下:
public int findMedianinTwoSortedAray(int[] arr1, int[] arr2) {
return find(arr1,0,arr1.length,arr2,0,arr2.length);
}
int find(int[] arr1, int left1, int rigth1, int[] arr2, int left2, int rigth2) {
int mid1 = (rigth1 - left1-1) / 2 + left1;
int mid2 = (rigth2 - left2-1) / 2 + left2;
if (arr1[mid1]==arr2[mid2]){
return arr1[mid1];
}
if (rigth1 - left1 == 1){
return Math.min(arr1[left1],arr2[left2]);
}
if ((rigth1-left1)%2==1){
if (arr1[mid1]>arr2[mid2]){
return find(arr1,left1,mid1+1,arr2,mid2,rigth2);
}else {
return find(arr1,mid1,rigth1,arr2,left2,mid2+1);
}
}else {
if (arr1[mid1]>arr2[mid2]){
return find(arr1,left1,mid1+1,arr2,mid2+1,rigth2);
}else {
return find(arr1,mid1+1,rigth1,arr2,left2,mid2+1);
}
}
}
重点推理,就是每次二分之后剩余的数组的中上位数,为全部数组的中上位数。大家可以用画图的方案,来推理一下。
然后要分一下奇数偶数中间位保留跟丢弃的情况。