image.png

解题思路

image.png

  1. public double findMedianSortedArrays(int[] nums1, int[] nums2) {
  2. int m = nums1.length;
  3. int n = nums2.length;
  4. //处理任何一个nums为空数组的情况
  5. if (m == 0) {
  6. if (n % 2 != 0)
  7. return 1.0 * nums2[n / 2];
  8. return (nums2[n / 2] + nums2[n / 2 - 1]) / 2.0;
  9. }
  10. if (n == 0) {
  11. if (m % 2 != 0)
  12. return 1.0 * nums1[m / 2];
  13. return (nums1[m / 2] + nums1[m / 2 - 1]) / 2.0;
  14. }
  15. int total = m + n;
  16. //总数为奇数,找第 total / 2 + 1 个数
  17. if ((total & 1) == 1) {
  18. return find_kth(nums1, 0, nums2, 0, total / 2 + 1);
  19. }
  20. //总数为偶数,找第 total / 2 个数和第total / 2 + 1个数的平均值
  21. return (find_kth(nums1, 0, nums2, 0, total / 2) + find_kth(nums1, 0, nums2, 0, total / 2 + 1)) / 2.0;
  22. }
  23. //寻找a 和 b 数组中,第k个数字
  24. double find_kth(int[] a, int a_begin, int[] b, int b_begin, int k) {
  25. //当a 或 b 超过数组长度,则第k个数为另外一个数组第k个数
  26. if (a_begin >= a.length)
  27. return b[b_begin + k - 1];
  28. if (b_begin >= b.length)
  29. return a[a_begin + k - 1];
  30. //k为1时,两数组最小的那个为第一个数
  31. if (k == 1)
  32. return Math.min(a[a_begin], b[b_begin]);
  33. int mid_a = Integer.MAX_VALUE;
  34. int mid_b = Integer.MAX_VALUE;
  35. //mid_a / mid_b 分别表示 a数组、b数组中第 k / 2 个数
  36. if (a_begin + k / 2 - 1 < a.length)
  37. mid_a = a[a_begin + k / 2 - 1];
  38. if (b_begin + k / 2 - 1 < b.length)
  39. mid_b = b[b_begin + k / 2 - 1];
  40. //如果a数组的第 k / 2 个数小于b数组的第 k / 2 个数,表示总的第 k 个数位于 a的第k / 2个数的后半段,或者是b的第 k / 2个数的前半段
  41. //由于范围缩小了 k / 2 个数,此时总的第 k 个数实际上等于新的范围内的第 k - k / 2个数,依次递归
  42. if (mid_a < mid_b)
  43. return find_kth(a, a_begin + k / 2, b, b_begin, k - k / 2);
  44. //否则相反
  45. return find_kth(a, a_begin, b, b_begin + k / 2, k - k / 2);
  46. }