[关闭]
@snuffles 2019-04-04T15:54:17.000000Z 字数 1302 阅读 987

L4 寻找两个有序数组的中位数

搜索 数组


给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。

解:限制了时间复杂度,中位数定义,奇数为中间那个,偶数为中间连个数字平均。即求(m+n+1)/2和(m+n+2)/2的平均(其中如果M+N为奇数,(m+n+1)/2=(m+n+2)/2);
在两个数组间使用二分法,要找到总的第K个数字,先在每个数组里找K/2,扔掉一半,直到K缩小到1,选两个数组里较小的那个为第K个数字。

  1. class Solution {
  2. public:
  3. //返回值double注意/2.0
  4. double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
  5. int len1 = nums1.size();
  6. int len2 = nums2.size();
  7. //special case // len==1 注意位置=长度-1
  8. // 1,2,3,4
  9. if(len1 == 0){
  10. if(len2 >1)
  11. return (nums2[(len2+1)/2-1] + nums2[(len2+2)/2-1])/2.0;
  12. else return nums2[0];
  13. }
  14. if(len2 == 0 ){
  15. if(len1>1)
  16. return (nums1[(len1+1)/2-1] + nums1[(len1+2)/2-1])/2.0;
  17. else return nums1[0];
  18. }
  19. //find in two array
  20. // 1,2,3;
  21. // 3,4,5; 1,2,3,3,4,5;
  22. int k1 = (len1+len2+1)/2; //3
  23. int k2 = (len1+len2+2)/2; //4
  24. return (find(nums1,0,nums2,0,k1)+find(nums1,0,nums2,0,k2))/2.0 ;
  25. }
  26. int find(vector<int> nums1,int i,vector<int> nums2, int j, int k){
  27. // judge in range;
  28. if(nums1.size() <= i) return nums2[j+k-1];
  29. if(nums2.size() <= j) return nums1[i+k-1];
  30. // special case;
  31. if(k==1) return min(nums1[i],nums2[j]);
  32. // find k in nums1 from pos i;
  33. int mid1,mid2;
  34. if((i+ k/2 -1)<nums1.size()){
  35. mid1 = nums1[i+ k/2 -1];
  36. }
  37. else mid1 = INT_MAX;
  38. // find k in nums2 from pos j;
  39. if((j+ k/2 -1)<nums2.size()){
  40. mid2 = nums2[j+ k/2 -1];
  41. }
  42. else mid2 = INT_MAX;
  43. // compare mid1,mid2
  44. if(mid1 < mid2) return find(nums1,i+k/2,nums2,j,k-k/2);
  45. else return find(nums1,i,nums2,j+k/2,k-k/2);
  46. }
  47. };
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注