当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度: Hard

内容描述

  1. 有两个大小分别为mn的排序数组nums1nums2
  2. 求两个排序数组的中值。总体运行时复杂性应该是Ologm+n))。
  3. 您可以假设nums1nums2不能同时为空。
  4. Example 1:
  5. nums1 = [1, 3]
  6. nums2 = [2]
  7. The median is 2.0
  8. Example 2:
  9. nums1 = [1, 2]
  10. nums2 = [3, 4]
  11. The median is (2 + 3)/2 = 2.5

解题方案

思路 1
**- 时间复杂度: O(log(m + n))**- 空间复杂度: O(1)**

将问题转化为两个有序数组,找出其中的第K大的数, beats 99.80%

  1. class Solution {
  2. // 寻找两个有序数组的中位数
  3. // 问题转换为求第K大的数
  4. public double findMedianSortedArrays(int[] nums1, int[] nums2) {
  5. if(nums1 == null || nums1.length == 0){
  6. // 求nums2的中位数
  7. return nums2.length % 2 == 0 ? (nums2[nums2.length / 2] + nums2[nums2.length / 2 - 1]) / 2.0 : nums2[nums2.length / 2];
  8. }
  9. if(nums2 == null || nums2.length == 0){
  10. return nums1.length % 2 == 0 ? (nums1[nums1.length / 2] + nums1[nums1.length / 2 - 1]) / 2.0 : nums1[nums1.length / 2];
  11. }
  12. int len = nums1.length + nums2.length;
  13. return len % 2 == 0 ? (topK(nums1,nums2,0,0,len/2)+topK(nums1,nums2,0,0,len/2+1))/2.0 : topK(nums1,nums2,0,0,len/2 + 1);
  14. }
  15. // 找两个有序数组的topk小的数
  16. public int topK(int[] nums1,int[] nums2,int start1,int start2,int k){
  17. if(start1 >= nums1.length){
  18. return nums2[start2 + k - 1];
  19. }
  20. if(start2 >= nums2.length){
  21. return nums1[start1 + k - 1];
  22. }
  23. if(k == 1){
  24. return Math.min(nums1[start1] , nums2[start2]);
  25. }
  26. if(start1 + k / 2 > nums1.length){ // 肯定不会在nums2的前 k / 2
  27. return topK(nums1,nums2,start1,start2 + k / 2,k - k / 2);
  28. }else if(start2 + k / 2 > nums2.length){
  29. return topK(nums1,nums2,start1 + k / 2,start2,k - k / 2);
  30. }
  31. int mid1 = nums1[start1 + k / 2 - 1];
  32. int mid2 = nums2[start2 + k / 2 - 1];
  33. if(mid1 > mid2){ // 移除nums2的前k/2
  34. return topK(nums1,nums2,start1,start2 + k / 2,k - k / 2);
  35. }else {
  36. return topK(nums1,nums2,start1 + k / 2,start2,k - k/2);
  37. }
  38. }
  39. }

该分类下的相关小册推荐: