题意:
求两个有序数组a(含m个元素), b(含n个元素)的中位数。(偶数个数的情况下为中间两个数的平均数)
思路:
理解中位数的用途是把一个集合分成两部分,使其中一部分总是大于另一部分。
将数组a分成左、右两部分,将数组b分成左、右两部分。再将两个左部分合并为left,两个右部分合并为right。能够使left和right的元素个数相等(或相差不超过一个)同时max(left) <= min(right)即可。
可以用二分来做。复杂度O(log(min(m, n)))。
实现:
1 class Solution 2 { 3 public: 4 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) 5 { 6 int m = nums1.size(); int n = nums2.size(); 7 if(m > n) 8 { 9 vector<int> tmp = nums1; 10 nums1 = nums2; 11 nums2 = tmp; 12 m = nums1.size(); 13 n = nums2.size(); 14 } 15 int left = 0; 16 int right = m; 17 int i, j; 18 double maxL, minR, ans; 19 while (left <= right) 20 { 21 i = (left + right) >> 1; 22 j = (m + n + 1) / 2 - i; 23 if ((i == 0 || j == n || nums1[i - 1] <= nums2[j]) && 24 (j == 0 || i == m || nums2[j - 1] <= nums1[i])) 25 { 26 if (i == 0) 27 maxL = nums2[j - 1]; 28 else if (j == 0) 29 maxL = nums1[i - 1]; 30 else 31 maxL = max(nums1[i - 1], nums2[j - 1]); 32 if ((m + n) & 1) 33 ans = maxL; 34 else 35 { 36 if (i == m) 37 minR = nums2[j]; 38 else if (j == n) 39 minR = nums1[i]; 40 else 41 minR = min(nums1[i], nums2[j]); 42 ans = (maxL + minR) / 2.0; 43 } 44 break; 45 } 46 else if (i > 0 && nums1[i - 1] > nums2[j]) 47 { 48 right = i - 1; 49 } 50 else 51 { 52 left = i + 1; 53 } 54 } 55 return ans; 56 } 57 int max(int a, int b) 58 { 59 return a > b ? a : b; 60 } 61 int min(int a, int b) 62 { 63 return a < b ? a : b; 64 } 65 };
总结:
在c++中,引用相当于一个别名。
例如:
int m;
int &n = m;
n相当于m的别名(绰号),对n的任何操作就是对m的操作。
所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。
引用的规则:
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
以下示例程序中,k被初始化为i的引用。
语句k = j并不能将k修改成为j的引用,只是把k的值改变成为6。
由于k是i的引用,所以i的值也变成了6。
int i = 5;
int j = 6;
int &k = i;
k = j; // k和i的值都变成了6;
关于“引用”部分的内容引自 http://www.cnblogs.com/kingln/archive/2008/03/29/1129118.html