个人随笔
目录
leetcode(二)、寻找两个正序数组的中位数
2021-06-15 18:35:21

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

  • 示例 1:输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2
  • 示例 2:输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) /2 = 2.5
  • 示例 3:输入:nums1 = [0,0], nums2 = [0,0] 输出:0.00000
  • 示例 4:输入:nums1 = [], nums2 = [1] 输出:1.00000
  • 示例 5:输入:nums1 = [2], nums2 = [] 输出:2.00000
    提示:
    nums1.length == m nums2.length == n 0 <= m <= 1000 0 <= n <= 1000 1 <= m + n<= 2000 -106 <= nums1[i], nums2[i] <= 106

进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?(我表示没有做到)

  1. class Test4 {
  2. /**
  3. * 直接用归并排序来做排序,然后取中位数即可
  4. * 执行用时:78 ms, 在所有 Java 提交中击败了5.14%的用户 内存消耗:39.8 MB, 在所有 Java 提交中击败了33.73%的用户
  5. * 扎心,看来排序不靠谱O(N*lgN)
  6. */
  7. public double findMedianSortedArrays(int[] nums1, int[] nums2) {
  8. // 设置中位数的值
  9. double result = 0d;
  10. if (nums1.length == 0 && nums2.length == 0) {
  11. return result;
  12. }
  13. // 对左边进行归并排序
  14. mergeSort(nums1, 0, nums1.length - 1);
  15. System.out.println("nums1排序之后:");
  16. for (int i = 0; i < nums1.length; i++) {
  17. System.out.print(nums1[i] + " ");
  18. }
  19. // 对右边进行归并排序
  20. mergeSort(nums2, 0, nums2.length - 1);
  21. System.out.println("nums2排序之后:");
  22. for (int i = 0; i < nums2.length; i++) {
  23. System.out.print(nums2[i] + " ");
  24. }
  25. // 对两边进行合并
  26. int[] nums = new int[nums1.length + nums2.length];
  27. mergeNums1Nums2(nums, nums1, nums2);
  28. System.out.println("nums排序之后:");
  29. for (int i = 0; i < nums.length; i++) {
  30. System.out.print(nums[i] + " ");
  31. }
  32. // 取中位数
  33. int mid = nums.length / 2;
  34. if (nums.length % 2 == 0) {
  35. // 表明是偶数,取中间的和上一个相加
  36. result = (nums[mid] + nums[mid - 1]) / 2d;
  37. } else {
  38. result = nums[mid];
  39. }
  40. System.out.println("中位数:" + result);
  41. return result;
  42. }
  43. private void mergeNums1Nums2(int[] nums, int[] nums1, int[] nums2) {
  44. int nums1_left = 0;
  45. int nums1_right = nums1.length - 1;
  46. int nums2_left = 0;
  47. int nums2_right = nums2.length - 1;
  48. int now = 0;
  49. while (nums1_left <= nums1_right && nums2_left <= nums2_right) {
  50. // 从两个数组中选取较小的数放入中间数组
  51. if (nums1[nums1_left] <= nums2[nums2_left]) {
  52. nums[now] = nums1[nums1_left];
  53. nums1_left++;
  54. } else {
  55. nums[now] = nums2[nums2_left];
  56. nums2_left++;
  57. }
  58. now++;
  59. }
  60. // 将剩余的部分放入中间数组
  61. while (nums1_left <= nums1_right) {
  62. nums[now] = nums1[nums1_left];
  63. nums1_left++;
  64. now++;
  65. }
  66. while (nums2_left <= nums2_right) {
  67. nums[now] = nums2[nums2_left];
  68. nums2_left++;
  69. now++;
  70. }
  71. }
  72. private void mergeSort(int[] a, int left, int right) {
  73. if (left < right) {
  74. int middle = (left + right) / 2;
  75. // 对左边进行递归
  76. mergeSort(a, left, middle);
  77. // 对右边进行递归
  78. mergeSort(a, middle + 1, right);
  79. // 合并
  80. merge(a, left, middle, right);
  81. }
  82. }
  83. private void merge(int[] a, int left, int middle, int right) {
  84. int[] tmpArr = new int[a.length];
  85. int mid = middle + 1; // 右边的起始位置
  86. int tmp = left;
  87. int third = left;
  88. while (left <= middle && mid <= right) {
  89. // 从两个数组中选取较小的数放入中间数组
  90. if (a[left] <= a[mid]) {
  91. tmpArr[third++] = a[left++];
  92. } else {
  93. tmpArr[third++] = a[mid++];
  94. }
  95. }
  96. // 将剩余的部分放入中间数组
  97. while (left <= middle) {
  98. tmpArr[third++] = a[left++];
  99. }
  100. while (mid <= right) {
  101. tmpArr[third++] = a[mid++];
  102. }
  103. // 将中间数组复制回原数组
  104. while (tmp <= right) {
  105. a[tmp] = tmpArr[tmp++];
  106. }
  107. }
  108. public static void main(String[] args) {
  109. int[] num1 = { 1, 2 };
  110. int[] num2 = { 3, 4 };
  111. new Test4().findMedianSortedArrays(num1, num2);
  112. }
  113. }

丢人,超过的人太少了!

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

 132

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2