LeetCode: Median of Two Sorted Arrays 解題報告


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

SOLTION 1:

1. 我們借用findKthNumber的思想。先實現findKthNumber,如果是偶數個,則把中間2個加起來平均,奇數就用中間的。

2. 為了達到LOG級的復雜度,我們可以這樣:

每次在A,B取前k/2個元素。有以下這些情況:

1).  A的元素個數 < k/2. 則我們可以丟棄B前k/2. 反之亦然

證明:

我們使用反證法。

假設第K大在B的前k/2中,例如位置在索引m(m <= k/2-1)那么A必然擁有前k中的k -(m+1)個元素,而

m <= k/2-1,則 m+1 <= k/2  , k - (m+1) >= k/2與條件:A的元素不夠k/2矛盾,所以假設不成立,得證。

舉個栗子:

A: 6 7 8

B: 1 2 3 4 5

找第8大的數字,

2). A[mid] < B[mid] (mid是k/2 -1索引處的元素)。

這種情況下,我們可以丟棄A前k/2。

證明:

我們使用反證法。

假設第K大在A的前k/2中記為maxK,例如位置在索引m(m <= k/2-1)那么B必然擁有前k中的k -(m+1)個元素,而

m <= k/2-1,則 m+1 <= k/2  , k - (m+1) > k/2

推出B[mid] <= maxK

而A[mid] >= maxK 推出 A[mid]>=B[mid], 與題設矛盾。所以假設不能成立。

舉個栗子:

A: 1 2

B: 4 5 6 7 8

找第四大的數字 我們就可以首先排除1,2.

 1 public double findMedianSortedArrays(int A[], int B[]) {
 2         if (A == null || B == null) {
 3             return 0;
 4         }
 5         
 6         int len = A.length + B.length;
 7         
 8         double ret = 0;
 9         // 偶數個元素
10         if (len % 2 == 0) {
11             ret = (findKth(A, B, 0, 0, len / 2) + findKth(A, B, 0, 0, len / 2 + 1)) / (double)2.0;
12         } else {
13             // 奇數個元素
14             ret = findKth(A, B, 0, 0, len / 2 + 1);            
15         }
16         
17         return ret;
18     }
19     
20     // Find the Kth large number.
21     public int findKth(int A[], int B[], int indexA, int indexB, int k) {
22         int lenA = A.length;
23         int lenB = B.length;
24         
25         if (indexA >= lenA) {
26             return B[indexB + k - 1];
27         } else if (indexB >= lenB) {
28             return A[indexA + k - 1];
29         }
30         
31         // Base Case, pay attention. 在這里必須要退出。因為k = 1的時候,不可能再分了。
32         if (k == 1) {
33             return Math.min(A[indexA], B[indexB]);
34         }
35         
36         // -1是因為索引本身是從0開始的。而前k大元素含有k個元素。
37         int mid = k / 2 - 1;
38         
39         // 注意,越界條件是 >= lenA. 怎么老是犯這個錯誤。。
40         int keyA = indexA + mid >= lenA ? Integer.MAX_VALUE: A[indexA + mid];
41         int keyB = indexB + mid >= lenB ? Integer.MAX_VALUE: B[indexB + mid];
42         
43         // 因為丟棄了k / 2個元素
44         int kNew = k - k / 2;
45         
46         if (keyA < keyB) {
47             return findKth(A, B, indexA + k / 2, indexB, kNew);
48         } else {
49             return findKth(A, B, indexA, indexB + k / 2, kNew);
50         }
51     }
View Code

 2015.1.25

可以優化一下,在找到kth number時可以及時退出:

 1 public class Solution {
 2     public double findMedianSortedArrays(int A[], int B[]) {
 3         //2257
 4         if (A == null || B == null) {
 5             return 0;
 6         }
 7         
 8         int len = A.length + B.length;
 9         if (len % 2 == 0) {
10             return (double)(dfs(A, B, 0, 0, len / 2) + dfs(A, B, 0, 0, len / 2 + 1)) / 2.0;
11         } else {
12             return dfs(A, B, 0, 0, len / 2 + 1);
13         }
14     }
15     
16     public double dfs1(int A[], int B[], int aStart, int bStart, int k) {
17         if (aStart >= A.length) {
18             return B[bStart + k - 1];
19         } else if (bStart >= B.length) {
20             return A[aStart + k - 1];
21         }
22         
23         if (k == 1) {
24             return Math.min(A[aStart], B[bStart]);
25         }
26         
27         // k = 4;
28         // mid = 1;
29         int mid = k / 2 - 1;
30         
31         if (aStart + mid >= A.length) {
32             // drop the left side of B.
33             return dfs(A, B, aStart, bStart + k / 2, k - k / 2);
34         } else if (bStart + mid >= B.length) {
35             // drop the left side of A.
36             return dfs(A, B, aStart + k / 2, bStart, k - k / 2);
37         } else if (A[aStart + mid] > B[bStart + mid]) {
38             // drop the left side of B.
39             return dfs(A, B, aStart, bStart + k / 2, k - k / 2);
40         // 當2者相等,有2種情況:
41         // 1. 當k為偶數,則kth存在於任何一個結尾處,其實也是可以丟棄一半的。
42         // 2. 當k為奇數,則kth不存在於A,B的left side。也是可以丟棄任意一半。
43         //} else if (A[aStart + mid] < B[bStart + mid]) {
44         } else {
45             return dfs(A, B, aStart + k / 2, bStart, k - k / 2);
46         }
47         
48         //return A[aStart + mid];        
49     }
50     
51     public double dfs(int A[], int B[], int aStart, int bStart, int k) {
52         if (aStart >= A.length) {
53             return B[bStart + k - 1];
54         } else if (bStart >= B.length) {
55             return A[aStart + k - 1];
56         }
57         
58         if (k == 1) {
59             return Math.min(A[aStart], B[bStart]);
60         }
61         
62         // k = 4;
63         // mid = 1;
64         int mid = k / 2 - 1;
65         
66         if (aStart + mid >= A.length) {
67             // drop the left side of B.
68             return dfs(A, B, aStart, bStart + k / 2, k - k / 2);
69         } else if (bStart + mid >= B.length) {
70             // drop the left side of A.
71             return dfs(A, B, aStart + k / 2, bStart, k - k / 2);
72         } else if (A[aStart + mid] > B[bStart + mid]) {
73             // drop the left side of B.
74             return dfs(A, B, aStart, bStart + k / 2, k - k / 2);
75         } else if (A[aStart + mid] < B[bStart + mid]) {
76             return dfs(A, B, aStart + k / 2, bStart, k - k / 2);
77         } else {
78             // drop the left side of A.
79             //return dfs(A, B, aStart + k / 2, bStart, k - k / 2);
80             if (k % 2 == 0){
81                 return A[aStart + mid];
82             }
83             
84             // can drop both sides.
85             return dfs(A, B, aStart + k / 2, bStart + k / 2, 1);
86         }
87         
88         //return A[aStart + mid];        
89     }
90 }
View Code

 

GITHUB:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/array/FindMedianSortedArrays.java


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM