题目: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)).
分析:这题很难,要求时间复杂度为log(m+n)。给出两个已经排好序的数组,要求找出两个数组中的中点元素。想了很久也没有想出怎么做,下面给出了三中解法,第一种是我自己写的,后面两种是我在网上看了,觉得比较好的解法。
代码:
#include "stdafx.h" #include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; //寻找两个已排好序的数组的中点 class Solution{ public: int findMedianSortedArrays(int A[], int m, int B[], int n){ int total = m + n; int am = 0; int bn = 0; vector<int> arr; for (int i = 0;i<total;i++){ if (bn < n && am < m){ if (A[am] > B[bn]){ arr.push_back(B[bn++]); }else{ arr.push_back(A[am++]); } }else if(bn >= n){ arr.push_back(A[am++]); }else{ arr.push_back(B[bn++]); } } return arr[total/2]; } int findMedianSortedArrays2(int A[], int m, int B[], int n){ int total = m + n; //判断奇偶,0x1十六进制1 if (total & 0x1){ //奇 return find_kth(A, m, B, n, total / 2 + 1); } else{ //偶 return (find_kth(A, m, B, n, total / 2) + find_kth(A, m, B, n, total / 2 + 1)) / 2.0; } } int findMedianSortedArrays3(int A[], int m, int B[], int n){ int total = m + n; int* a = new int[total]; memcpy(a,A,sizeof(int)*m); memcpy(a+m,B,sizeof(int)*n); //sort(a,a + total, less<int>()); sort(a,a + total); int rtn = a[total>>1]; //除以2,则右移一位 delete a; return rtn; } private: //递归,求两个数组的中点 int find_kth(int A[], int m, int B[], int n, int k) { if (m > n) return find_kth(B, n, A, m, k); //始终认为m<=n(前面数组比后面数组短),这样便于处理 //递归终止条件 if (m == 0) return B[k - 1]; if (k == 1) return min(A[0], B[0]); //将k划分为两部分 int ia = min(k / 2, m); int ib = k - ia; if (A[ia - 1] < B[ib - 1]) return find_kth(A + ia, m - ia, B, n, k - ia); else if (A[ia - 1] > B[ib - 1]) return find_kth(A, m, B + ib, n - ib, k - ib); else return A[ia - 1]; } };都认为第三种解法最好,的确,时间复杂度符合要求。可以说是要背下来的解法,这种解法可以解决求两个已排序数组中第k大的元素。