LeetCode:Median of Two Sorted Arrays

悠悠 2022-07-12 07:43 248阅读 0赞

第四题是找两个已经排序的数组的中位数,其实就是寻找两个排序数组的第k个数。寻找第k个数就需要把k均分到两个数组,可以用到结论如果a[k/2-1]小雨b[k/2-1],那么a[0]-a[k/2-1]必定存在于第k小的有序数列中。

解题思路如下,还是非常经典的。

  • 保持前一个数组A最短, 后一个数组B较长
  • 平分k, 一半在数组A,一半在数组B,如果A的长度不够长,那么pa = min(k/2, len(A)) pb = k-pa
  • 如果A[pa-1] < B[pb-1],那么第k个数组肯定不会出现在pa之前的A中,将A的pa之前的序列砍掉,B也同理,递归进行。

边界条件

  • m==0,A已经用完,直接返回B[k-1]
  • k==1,找到第一个数,返回min(A[0], B[0])
  • A[pa - 1] == B[pb - 1], A[pa - 1]和B[pb - 1]任意一个就是要找的数。

C++代码

  1. #include <cstdio>
  2. #include <vector>
  3. #include <algorithm>
  4. using std::vector;
  5. class Solution {
  6. public:
  7. double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
  8. int n1 = nums1.size();
  9. int n2 = nums2.size();
  10. int count = n1 + n2;
  11. if (count & 0x01) {
  12. return findKth(nums1, 0, n1, nums2, 0, n2, count/2 + 1);
  13. } else {
  14. return (findKth(nums1, 0, n1, nums2, 0, n2, count/2)
  15. + findKth(nums1, 0, n1, nums2, 0, n2, count/2 + 1)) / 2.0;
  16. }
  17. }
  18. private:
  19. double findKth(vector<int>& nums1, int s1, int e1,
  20. vector<int>& nums2, int s2, int e2, int k) {
  21. int m = e1 - s1;
  22. int n = e2 - s2;
  23. if (m > n) {
  24. return findKth(nums2, s2, e2, nums1, s1, e1, k);
  25. }
  26. if (m == 0) {
  27. return nums2[s2 + k - 1];
  28. }
  29. if (k == 1) {
  30. return std::min(nums1[s1], nums2[s2]);
  31. }
  32. int pa = std::min(k/2, m);
  33. int pb = k - pa;
  34. if (nums1[s1 + pa - 1] < nums2[s2 + pb - 1]) {
  35. return findKth(nums1, s1 + pa, e1, nums2, s2, e2, k - pa);
  36. } else if (nums1[s1 + pa -1] > nums2[s2 + pb - 1]) {
  37. return findKth(nums1, s1, e1, nums2, s2 + pb, e2, k - pb);
  38. } else {
  39. return nums1[s1 + pa - 1];
  40. }
  41. }
  42. };
  43. int main()
  44. {
  45. Solution s;
  46. vector<int> v1, v2;
  47. v1.clear();
  48. v2.clear();
  49. v1.push_back(2);
  50. // v1.push_back(3);
  51. // v1.push_back(5);
  52. // v1.push_back(7);
  53. // v1.push_back(9);
  54. // v2.push_back(2);
  55. // v2.push_back(4);
  56. // v2.push_back(6);
  57. // v2.push_back(8);
  58. // v2.push_back(10);
  59. double median = s.findMedianSortedArrays(v1, v2);
  60. printf("median:%.2f\", median); return 0; }

python代码

  1. #! /usr/bin/env python
  2. # -*- coding:utf8 -*-
  3. class Solution(object):
  4. def findKth(self, nums1, nums2, k):
  5. m = len(nums1)
  6. n = len(nums2)
  7. if m > n:
  8. return self.findKth(nums2, nums1, k)
  9. if m == 0:
  10. return nums2[k - 1]
  11. if k == 1:
  12. return min(nums1[0], nums2[0])
  13. p1 = min(k/2, m)
  14. p2 = k - p1
  15. if nums1[p1 - 1] < nums2[p2 - 1]:
  16. return self.findKth(nums1[p1:m], nums2, k - p1)
  17. elif nums2[p2 - 1] < nums1[p1 - 1]:
  18. return self.findKth(nums1, nums2[p2:n], k - p2)
  19. else:
  20. return nums1[p1 - 1]
  21. def findMedianSortedArrays(self, nums1, nums2):
  22. """ :type nums1: List[int] :type nums2: List[int] :rtype: float """
  23. count = len(nums1) + len(nums2)
  24. if count & 0x1:
  25. return self.findKth(nums1, nums2, count/2 + 1)
  26. else:
  27. return (self.findKth(nums1, nums2, count/2) + self.findKth(nums1, nums2, count/2 + 1))*1.0/2
  28. if __name__ == "__main__":
  29. s = Solution()
  30. print s.findMedianSortedArrays([2], [])
  31. print s.findMedianSortedArrays([], [2])
  32. print s.findMedianSortedArrays([1, 3, 5, 7], [2, 4, 6, 8, 10])
  33. print s.findMedianSortedArrays([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])

时间复杂度,整个算法利用了二分查找的思想,二分查找的复杂度为log(n),序列长度为m+n,所以整个时间复杂度是log(m+n)

发表评论

表情:
评论列表 (有 0 条评论,248人围观)

还没有评论,来说两句吧...

相关阅读

    相关 LeetCode:Median of Two Sorted Arrays

    第四题是找两个已经排序的数组的中位数,其实就是寻找两个排序数组的第k个数。寻找第k个数就需要把k均分到两个数组,可以用到结论如果a\[k/2-1\]小雨b\[k/2-1\],那