LeetCode Online Judge 题目C# 练习 - 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)).

 1         public static double MedianofTwoSortedArrays(int[] A, int[] B)

 2         {

 3             int m = A.Length;

 4             int n = B.Length;

 5 

 6             if (m + n <= 1)

 7             {

 8                 if (m == 0)

 9                     return B[0];

10                 else if (n == 0)

11                     return A[0];

12             }

13             int mid1 = 0, mid2 = 0;

14 

15             //if m + n % 2 == 0, mid2 = mid + 1; else mid1 = mid2 = (m + n) / 2 + 1;

16             mid1 = (m + n) / 2 + (m + n) % 2;

17             mid2 = (m + n) / 2 + 1;

18 

19             int pa = 0, pb = 0, count = 0;

20             double median1 = 0, median2 = 0;

21             

22             //merge two array and keep counting. set median1 and median2 when count = mid1 or mid2 respectively.

23             while (count < mid2)

24             {

25                 if ((pa < m && A[pa] <= B[pb]) || pa >= n)

26                 {

27                     count++;

28                     if (count == mid1)

29                         median1 = A[pa];

30                     if (count == mid2)

31                         median2 = A[pa];

32                     pa++;

33                 }

34                 else

35                 {

36                     count++;

37                     if (count == mid1)

38                         median1 = B[pb];

39                     if (count == mid2)

40                         median2 = B[pb];

41                     pb++;

42                 }

43             }

44 

45             return (median1 + median2) / 2;

46         }

代码分析:

  O(m + n)的做法,把mid1 和 mid2 算出来,如果总长 m + n 是odd, mid1 = mid2, 如果是even, mid2 = mid1 + 1.

  然后pa, pb 指针, merge两个数组同时count, 得到median1和median2后求出median。

  奇怪的是leetcode要求时间复杂度O(log(m+n)),这个O(m+n)的做法居然过了large case.

 1         public static double MedianofTwoSortedArraysOpt(int[] A, int[] B)

 2         {

 3             int t = A.Length + B.Length;

 4             if (t % 2 == 0)

 5             {

 6                 return ((double)FindKth(A, 0, A.Length, B, 0, B.Length, t / 2) +

 7                         (double)FindKth(A, 0, A.Length, B, 0, B.Length, t / 2 + 1)) / 2;

 8             }

 9 

10             return FindKth(A, 0, A.Length, B, 0, B.Length, t / 2 + 1);

11         }

12 

13         public static int FindKth(int[] A, int aoffset, int m, int[] B, int boffset, int n, int k)

14         {

15             //Keep the A is the shorter array.

16             if (m > n) FindKth(B, boffset, n, A, aoffset, m, k);

17 

18             if (m == 0) return B[k - 1];

19             if (k == 1) return Math.Min(A[aoffset], B[boffset]);

20 

21             //set pa and pb pointer

22             int pa = Math.Min(k / 2, m);

23             int pb = k - pa;

24 

25             if (A[aoffset + pa - 1] < B[boffset + pb - 1]) return FindKth(A, aoffset + pa, m - pa, B, boffset, n, k - pa);

26 

27             return FindKth(A, aoffset, m, B, boffset + pb, n - pb, k - pb);

28         }

代码分析:

  这个应该是O(log(k))的做法。因为找两个sorted array 的中位数,其实就是找第K个数的变体,如果m + n 是odd, 那就是找第 (m + n) / 2 个数,如果是even, 那就是找 (m + n) / 2, (m + n) / 2 + 1的平均值。

  这个FindKth()函数也是在mitbbs上看到的,非常牛。用C++写就更简洁了。

  还是想记下这个FindKth()的思路。

  1. 保持A是短的那一个数组,B是长的

  2. 平分k, 一半在A,一半在B (如果A的长度不足K/2,那就pa就指到最后一个)

  3. 如果pa的值 < pb的值,那证明第K个数肯定不会出现在pa之前,递归,把A数组pa之前的砍掉,同理递归砍B数组。(代码中pa - 1是A的index是为了方便,因为题目第K个数,K是从1开始算的)。

  4. 递归到 m == 0 (短的数组用完了) 就返回 B[k - 1], 或者k == 1(找第一个数)就返回min(A第一个数,B第一个数)。(代码中用A[aoffset],因为C#不支持指针,C++里A[0]的完了)。

你可能感兴趣的:(LeetCode)