题解一:双指针
题解思路: 使用两个指针分别指向两个数组,由于两个数组长度相等,所以如果看成一个大数组的话,这个数组的长度一定为偶数。每次移动两者较小值的指针。当i+j==len表明找到中位数。
图示:
复杂度分析:
时间复杂度: : 只要一个到达数组末尾,就结束循环
空间复杂度: : 没有申请额外的空间
实现如下:
class Solution { public: int findMedianinTwoSortedAray(vector<int>& arr1, vector<int>& arr2) { int i = 0,j = 0; //两个变量分别代表两个数组中索引 int len = arr1.size(); int ans; while(i+j<len){ //当i+j ==len 代表找到中位数 if(arr1[i]<arr2[j]) { ans = arr1[i]; ++i; }else{ ans = arr2[j]; ++j; } } return ans; } };
题解二:二分
题解思路:首先两个数组都为N且有序,那么两个数组中间值两边数的个数是相同(长度为奇数)的或者一边多一个(长度为偶数),所以要考虑长度的奇偶。
用mid1表示arr1中值index,mid2表示arr2中值index
- 长度为奇数
①arr1[mid1] > arr2[mid2]
arr1[mid1] 肯定大于 arr2[0:mid2) , arr2[mid2] 肯定小于 arr1(mid1:right] , 且 arr2[0:mid2) 与 arr1 (mid1:right] 长度相同,所以要是将 arr1 与 arr2 合并看出一个大数组,它们位于这个数组的两端。
所以中位数肯定在 arr1[0:mid1] 和 arr2[mid2:right] 中;
②arr1[mid1] < arr2[mid2]
同理: 中位数在 arr1[mid1:right] 与 arr2[0:mid2] 中;
③arr1[mid1] == arr2[mid2]
表明找到中位数。 - 长度为偶数
①arr1[mid1] > arr2[mid2]:
这时如果向下取整,对于 arr(mid:right] 长度要比 arr[0:mid) 多一个数;
所以 arr1 会比 arr2 多缩减一个数,因此中位数在 arr1[0:mid1] 与 arr2[mid2+1,right] 中;
②arr1[mid1] < arr2[mid2]:
同理: 中位数在 arr1[mid1+1,right] 与 arr2[0:mid2];
③ arr1[mid1] = arr2[mid2]
表明找到中位数。
图示:
复杂度分析:
时间复杂度: : 每次都缩减一半的范围
空间复杂度: : 没有申请额外空间
实现如下:
class Solution { public: /** * find median in two sorted array * @param arr1 int整型vector the array1 * @param arr2 int整型vector the array2 * @return int整型 */ //都为N // 如果每个只有一个元素,返回小的[1] [2] 返回1; int findMedianinTwoSortedAray(vector<int>& arr1, vector<int>& arr2) { // write code here int left1(0),left2(0); int right1(arr1.size()-1),right2(arr2.size()-1); while(left1<right1){ int mid1 = (left1+right1)>>1; int mid2 = (left2+right2)>>1; int cr = (right1-left1+1)%2 ==0 ? 1:0; //如果是偶数,那么有一个arr多缩减了一个数 if(arr1[mid1]==arr2[mid2]) return arr1[mid1]; //相等表明找到中位数 else if(arr1[mid1]>arr2[mid2]){ left2 = mid2 +cr; //判断是不是要多一移一位,偶数需要 arr2[mid2+cr: right2] ---arr1[0:mid1] right1 = mid1; } else { left1 = mid1 +cr; //arr1[mid1+cr: right1] ---arr2[0:mid2] right2 = mid2; } } return min(arr1[left1],arr2[left2]); //上中位数 } };