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)).
LeetCode: Median of Two Sorted Arrays 解题报告
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

你可能感兴趣的:(LeetCode)