本博客rss订阅地址: http://feed.cnblogs.com/blog/u/147990/rss

LeetCode:Median of Two Sorted Arrays

题目链接

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)).

求两个有序数组的中位数,如果总元素个数是偶数,中位数是中间两个元素的平均值

 

详细讲解请参考我的另一篇博文:求两个有序数组的中位数或者第k小元素,那篇博文中如果数组总元素个数是偶数,求的是上中位数。

对于那篇博文中的算法2,这一题不能简单的套用,因为如果按照算法2的删除规则,当元素个数是偶数时,有可能把某个中位数删除了,比如对于数组【3,4】,【1,2,5,6】,比较4、5后就会把第一个数组中的3删除,但是3是要参与中位数的计算的。因此对于偶数个数的数组,我们加了一些判断,但是很复杂,代码如下,这里不推荐这种做法

 1 class Solution {
 2 public:
 3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
 4         int mid_a = m/2, mid_b = n/2;
 5         if(m == 0)
 6         {
 7             if(n % 2 == 0)
 8                 return (B[mid_b] + B[mid_b-1]) / 2.0;
 9             else return B[mid_b];
10         }
11         else if(n == 0)
12         {
13             if(m % 2 == 0)
14                 return (A[mid_a] + A[mid_a-1]) / 2.0;
15             else return A[mid_a];
16         }
17     
18         if(m == 1)
19         {
20             if(n == 1)
21                 return (A[0] + B[0]) / 2.0;
22             if(n % 2 == 0)
23             {
24                 if(A[0] >= B[mid_b])
25                     return B[mid_b];
26                 else if(A[0] <= B[mid_b-1])
27                     return B[mid_b-1];
28                 else return A[0];
29             }
30             else
31             {
32                 if(A[0] >= B[mid_b+1])
33                     return (B[mid_b] + B[mid_b+1]) / 2.0;
34                 else if(A[0] <= B[mid_b-1])
35                     return (B[mid_b] + B[mid_b-1]) / 2.0;
36                 else return(B[mid_b] + A[0]) / 2.0;
37             }
38         }
39         else if(n == 1)
40         {
41             if(m % 2 == 0)
42             {
43                 if(B[0] >= A[mid_a])
44                     return A[mid_a];
45                 else if(B[0] <= A[mid_a-1])
46                     return A[mid_a-1];
47                 else return B[0];
48             }
49             else
50             {
51                 if(B[0] >= A[mid_a+1])
52                     return (A[mid_a] + A[mid_a+1]) / 2.0;
53                 else if(B[0] <= A[mid_a-1])
54                     return (A[mid_a] + A[mid_a-1]) / 2.0;
55                 else return(A[mid_a] + B[0]) / 2.0;
56             }
57         }
58         
59         bool flag = false;
60         if(m == 2 && n%2 == 0)
61         {
62                 if(A[0] <= B[0] && A[1] >= B[n-1])
63                     return (B[mid_b] + B[mid_b-1]) / 2.0;
64                 else if(A[0] >= B[0] && A[1] <= B[n-1])
65                     return findMedianSortedArrays(A, m, &B[1], n-2);
66                 flag = true;
67         }
68         else if(n == 2 && m%2 == 0)
69         {
70                 if(B[0] <= A[0] && B[1] >= A[m-1])
71                     return (A[mid_a] + A[mid_a-1]) / 2.0;
72                 else if(B[0] >= A[0] && B[1] <= A[m-1])
73                     return findMedianSortedArrays(&A[1], m-2, B, n);
74                 flag = true;
75         }
76         
77     
78             int cutLen = mid_a > mid_b ? mid_b:mid_a;
79             if(m%2 == 0 && n%2 == 0 && flag == false)cutLen--;
80             if(A[mid_a] == B[mid_b])
81             {
82                 if(m%2 == 0 && n%2 == 0)
83                     return (A[mid_a] + max(A[mid_a-1], B[mid_b-1])) / 2.0; 
84                 else 
85                     return (A[mid_a] + B[mid_b]) / 2.0;
86             }
87             else if(A[mid_a] < B[mid_b])
88                 return findMedianSortedArrays(&A[cutLen], m - cutLen, B, n - cutLen);
89             else return findMedianSortedArrays(A, m - cutLen, &B[cutLen], n-cutLen);
90         
91     }
92 };
View Code

我们可以对那篇博客中算法2稍作修改就可以求下中位数,因此当两个数组总元素时偶数时,求上中位数和下中位数,然后求均值

  1 class Solution {
  2 public:
  3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
  4         int mid_a = m/2, mid_b = n/2;
  5         if(m == 0)
  6         {
  7             if(n % 2 == 0)
  8                 return (B[mid_b] + B[mid_b-1]) / 2.0;
  9             else return B[mid_b];
 10         }
 11         else if(n == 0)
 12         {
 13             if(m % 2 == 0)
 14                 return (A[mid_a] + A[mid_a-1]) / 2.0;
 15             else return A[mid_a];
 16         }
 17         
 18         if((m+n) % 2)
 19             return helper_up(A, m, B, n);
 20         else return (helper_up(A, m, B, n) + helper_down(A, m, B, n)) / 2.0;
 21     }
 22     int helper_up(int A[], int m, int B[], int n)
 23     {
 24         int mid_a = m/2, mid_b = n/2;
 25         if(m == 1)
 26         {
 27             if(n == 1)
 28                 return A[0] < B[0] ? B[0] : A[0];
 29             if(n % 2 == 0)
 30             {
 31                 if(A[0] >= B[mid_b])
 32                     return B[mid_b];
 33                 else if(A[0] <= B[mid_b-1])
 34                     return B[mid_b-1];
 35                 else return A[0];
 36             }
 37             else
 38             {
 39                 if(A[0] >= B[mid_b+1])
 40                     return B[mid_b+1];
 41                 else if(A[0] <= B[mid_b])
 42                     return B[mid_b];
 43                 else return A[0];
 44             }
 45         }
 46         else if(n == 1)
 47         {
 48             if(m % 2 == 0)
 49             {
 50                 if(B[0] >= A[mid_a])
 51                     return A[mid_a];
 52                 else if(B[0] <= A[mid_a-1])
 53                     return A[mid_a-1];
 54                 else return B[0];
 55             }
 56             else
 57             {
 58                 if(B[0] >= A[mid_a+1])
 59                     return A[mid_a+1];
 60                 else if(B[0] <= A[mid_a])
 61                     return A[mid_a];
 62                 else return B[0];
 63             }
 64         }
 65         else
 66         {
 67             int cutLen = mid_a > mid_b ? mid_b:mid_a;//注意每次减去短数组的一半,如果数组长度n是奇数,一半是指n-1/2
 68             if(A[mid_a] == B[mid_b])
 69                 return A[mid_a];
 70             else if(A[mid_a] < B[mid_b])
 71                 return helper_up(&A[cutLen], m - cutLen, B, n - cutLen);
 72             else return helper_up(A, m - cutLen, &B[cutLen], n-cutLen);
 73         }
 74     }
 75     
 76     int helper_down(int A[], int m, int B[], int n)
 77     {
 78         int mid_a = (m-1)/2, mid_b = (n-1)/2;
 79         if(m == 1)
 80         {
 81             if(n == 1)
 82                 return A[0] < B[0] ? A[0] : B[0];
 83             if(n % 2 == 0)
 84             {
 85                 if(A[0] >= B[mid_b+1])
 86                     return B[mid_b+1];
 87                 else if(A[0] <= B[mid_b])
 88                     return B[mid_b];
 89                 else return A[0];
 90             }
 91             else
 92             {
 93                 if(A[0] >= B[mid_b])
 94                     return B[mid_b];
 95                 else if(A[0] <= B[mid_b-1])
 96                     return B[mid_b-1];
 97                 else return A[0];
 98             }
 99         }
100         else if(n == 1)
101         {
102             if(m % 2 == 0)
103             {
104                 if(B[0] >= A[mid_a+1])
105                     return A[mid_a+1];
106                 else if(B[0] <= A[mid_a])
107                     return A[mid_a];
108                 else return B[0];
109             }
110             else
111             {
112                 if(B[0] >= A[mid_a])
113                     return A[mid_a];
114                 else if(B[0] <= A[mid_a-1])
115                     return A[mid_a-1];
116                 else return B[0];
117             }
118         }
119         else
120         {
121             int cutLen = (m/2 > n/2 ? n/2:m/2);//注意每次减去短数组的一半,如果数组长度n是奇数,一半是指n-1/2
122             if(A[mid_a] == B[mid_b])
123                 return A[mid_a];
124             else if(A[mid_a] < B[mid_b])
125                 return helper_down(&A[cutLen], m - cutLen, B, n - cutLen);
126             else return helper_down(A, m - cutLen, &B[cutLen], n-cutLen);
127         }
128     }
129 };
View Code

最优雅的方法是调用那篇博客中算法3求两个有序数组第k小元素的方法            本文地址

 1 class Solution {
 2 public:
 3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
 4         int mid_a = m/2, mid_b = n/2;
 5         if(m == 0)
 6         {
 7             if(n % 2 == 0)
 8                 return (B[mid_b] + B[mid_b-1]) / 2.0;
 9             else return B[mid_b];
10         }
11         else if(n == 0)
12         {
13             if(m % 2 == 0)
14                 return (A[mid_a] + A[mid_a-1]) / 2.0;
15             else return A[mid_a];
16         }
17         
18         if((m+n) % 2)
19             return findKthSmallest(A, m, B, n, (m+n+1)/2);
20         else return (findKthSmallest(A, m, B, n, (m+n)/2) + findKthSmallest(A, m, B, n, (m+n)/2+1)) / 2.0;
21     }
22     //找到两个有序数组中第k小的数,k>=1
23     int findKthSmallest(int vec1[], int n1, int vec2[], int n2, int k)
24     {
25         //边界条件处理
26         if(n1 == 0)return vec2[k-1];
27         else if(n2 == 0)return vec1[k-1];
28         if(k == 1)return vec1[0] < vec2[0] ? vec1[0] : vec2[0];
29         
30         int idx1 = n1*1.0 / (n1 + n2) * (k - 1);
31         int idx2 = k - idx1 - 2;
32      
33         if(vec1[idx1] == vec2[idx2])
34             return vec1[idx1];
35         else if(vec1[idx1] < vec2[idx2])
36             return findKthSmallest(&vec1[idx1+1], n1-idx1-1, vec2, idx2+1, k-idx1-1);
37         else
38             return findKthSmallest(vec1, idx1+1, &vec2[idx2+1], n2-idx2-1, k-idx2-1);
39     }
40 };

【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3675220.html

posted @ 2014-04-19 16:18  tenos  阅读(2344)  评论(0编辑  收藏  举报

本博客rss订阅地址: http://feed.cnblogs.com/blog/u/147990/rss

公益页面-寻找遗失儿童