4. Median of Two Sorted Arrays - Hard - Leetcode解题报告

There are two sorted arrays nums1 and nums2 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)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

Related Topic: Array, Binary Search, Divide and Conquer

解题思路:通过分治法来削减题目的规模,需要分别处理总数为奇数或偶数的情况,将题目转化为求数组的第k个元素。递归的退出条件为:1.若当前index超出当前数组的长度,则从另一个数组中去求kth元素。2.若已经递归到最底层,k=1的情况,取两个数组中较小的值。递归中divide部分时,分别从两个数组取start + k/2th元素,由于最后求的是中位数,两个元素较小者所处的k/2th元素必然距离中位数更远,后面也不会被取到。这里选择去掉此部分的k/2个元素,减少问题的规模。

Time Complexity: O(log(m+n)), Space Complexity: O(1)

Java version:

 1 class Solution {
 2     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 3         int len = nums1.length + nums2.length;
 4         if (len % 2 == 0) {
 5             return (findKth(nums1, 0, nums2, 0, len / 2) + findKth(nums1, 0, nums2, 0, len / 2 + 1)) / 2.0;
 6         } else {
 7             return findKth(nums1, 0, nums2, 0, len / 2 + 1);
 8         }
 9     }
10     
11     private int findKth(int[] nums1, int startA, int[] nums2, int startB, int k) {
12         if (startA >= nums1.length) {
13             return nums2[startB + k - 1];
14         }
15         if (startB >= nums2.length) {
16             return nums1[startA + k - 1];
17         }
18         if (k == 1) {
19             return Math.min(nums1[startA], nums2[startB]);
20         }
21         
22         int keyA = startA + k / 2 - 1 < nums1.length ? nums1[startA + k / 2 - 1] : Integer.MAX_VALUE;
23         int keyB = startB + k / 2 - 1 < nums2.length ? nums2[startB + k / 2 - 1] : Integer.MAX_VALUE;
24         if (keyA < keyB) {
25             return findKth(nums1, startA + k / 2, nums2, startB, k - k / 2);
26         } else {
27             return findKth(nums1, startA, nums2, startB + k / 2, k - k / 2);
28         }
29     }
30 }

JavaScript version:

 1 /**
 2  * @param {number[]} nums1
 3  * @param {number[]} nums2
 4  * @return {number}
 5  */
 6 var findMedianSortedArrays = function(nums1, nums2) {
 7     var len = nums1.length + nums2.length;
 8     if (len % 2 == 0) {
 9         return (findKth(nums1, 0, nums2, 0, len / 2) + findKth(nums1, 0, nums2, 0, len / 2 + 1)) / 2.0;
10     } else {
11         return findKth(nums1, 0, nums2, 0, Math.floor(len / 2) + 1);
12     }
13 };
14 
15 var findKth = function(nums1, start1, nums2, start2, k) {
16     if (start1 >= nums1.length) {
17         return nums2[start2 + k - 1];
18     }
19     if (start2 >= nums2.length) {
20         return nums1[start1 + k - 1];
21     }
22     if (k == 1) {
23         return Math.min(nums1[start1], nums2[start2]);
24     }
25     
26     var key1 = start1 + Math.floor(k / 2) - 1 < nums1.length ? nums1[start1 + Math.floor(k / 2) - 1] : Number.MAX_SAFE_INTEGER;
27     var key2 = start2 + Math.floor(k / 2) - 1 < nums2.length ? nums2[start2 + Math.floor(k / 2) - 1] : Number.MAX_SAFE_INTEGER;
28     if (key1 < key2) {
29         return findKth(nums1, start1 + Math.floor(k / 2), nums2, start2, k - Math.floor(k / 2));
30     } else {
31         return findKth(nums1, start1, nums2, start2 + Math.floor(k / 2), k - Math.floor(k / 2));
32     }
33 };

Python version:

 1 class Solution:
 2     def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
 3         arr_len = len(nums1) + len(nums2)
 4         if arr_len % 2 == 0:
 5             return (self.findKth(nums1, 0, nums2, 0, arr_len // 2) + self.findKth(nums1, 0, nums2, 0, arr_len // 2 + 1)) / 2
 6         else:
 7             return self.findKth(nums1, 0, nums2, 0, arr_len // 2 + 1)
 8         
 9     def findKth(self, nums1: List[int], start1: int, nums2: List[int], start2: int, k: int) -> int:
10         if start1 >= len(nums1):
11             return nums2[start2 + k - 1]
12         if start2 >= len(nums2):
13             return nums1[start1 + k - 1]
14         if k == 1:
15             return min(nums1[start1], nums2[start2])
16         
17         key1 = nums1[start1 + k // 2 - 1] if (start1 + k // 2 - 1) < len(nums1) else sys.maxsize
18         key2 = nums2[start2 + k // 2 - 1] if (start2 + k // 2 - 1) < len(nums2) else sys.maxsize
19         if key1 < key2:
20             return self.findKth(nums1, start1 + k // 2, nums2, start2, k - k // 2)
21         else:
22             return self.findKth(nums1, start1, nums2, start2 + k // 2, k - k // 2)

猜你喜欢

转载自www.cnblogs.com/raymondwang/p/10903176.html