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)
4. Median of Two Sorted Arrays - Hard - Leetcode解题报告
原文:https://www.cnblogs.com/raymondwang/p/10903176.html