Median of Two Sorted Arrays
There are two sorted arrays A and B 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)).
这个题目是非常有名的面试题,
注意leetcode上面对中位数的定义是:
如果合并之后的数组元素个数是奇数,那么中位数就是中间的那位
如果合并之后的数组元素个数是奇数,那么中位数是中间两位的平均数
解题思路有三种
解法一:
使用合并排序,将两个数组重新排序成一个新的数组,这样在O(1)的时间可以找到中位数,排序的时间是O(n+m)
解法二:
先假设数组A的长度为m,数组B的长度为n
1. 先分别找出数组A和数组B的中位数 ma 和 mb,设A[i] = ma , B[j] = mb 然后比较大小
2. 如果 ma < mb, 即A[i] < B[j], 那么中位数一定在A[i..m] 和 B[1..j] 之间, 然后再这个区间再求中位数,递归查找
3. 如果 ma > mb, 即A[i] > B[j],那么中位数一定在A[1..i] 和 B[j..n] 之间,然后再这个区间再求中位数,递归查找
算法比较好理解,但是程序有两点需要注意:
1) 递归的base条件是,当其中一个数组元素个数只剩下小于等于2时,递归结束
2) 每次递归时,在两个数组中选择除去的元素一定要相等。比如说A数组减去两个元素,那么B数组也要减去两个,这样剩下的区间的中位数和原来的中位数是一样的
程序如下: 这个代码过了leetcode的所有case,算是bug free了。
/** * find median of two sorted array, the values in array may same * * <p> * The algorithm are: * </p> * <ol> * <li>Calculate the medians m1 and m2 of the input arrays A and B * respectively.</li> * <li>If m1 is less than m2, then the median located between * A[m-index(m1)..m] and B[0..index(m2)], index(m1),index(m2) are the index * of array A and B,repeat finding median recrusively</li> * <li>If m1 is greater than m2, then the median located between * A[0..index(m1)] and B[n-index(m2)..n] ,repeat finding median recrusively</li> * </ol> * */ static class FindMedian1 { public static double medianSelect(int[] A, int[] B) { if (A == null && B == null) { return -1; } else if ((A == null || A.length == 0) && B.length != 0) { return B.length % 2 == 1 ? B[(B.length - 1) / 2] : (B[(B.length - 1) / 2] + B[(B.length - 1) / 2 + 1]) / 2.0; } else if (B == null || B.length == 0 && A.length != 0) { return A.length % 2 == 1 ? A[(A.length - 1) / 2] : (A[(A.length - 1) / 2] + A[(A.length - 1) / 2 + 1]) / 2.0; } return findMedian(A, 0, A.length - 1, B, 0, B.length - 1); } public static double findMedian(int[] A, int p, int r, int[] B, int l, int h) { if (p == r) {// only one element left to compare return findMedianBaseCase1(A[p], B, l, h); } else if (l == h) { return findMedianBaseCase1(B[l], A, p, r); } else if (r == p + 1) { return findMedianBaseCase2(A[p], A[r], B, l, h); } else if (h == l + 1) { return findMedianBaseCase2(B[l], B[h], A, p, r); } int medA = (p + r) / 2; int medB = (l + h) / 2; if (A[medA] <= B[medB]) { int k = 0; if ((r - p + 1) % 2 == 0) { k = Math.min(medA - 1, h - medB - 1); } else { k = Math.min(medA, h - medB - 1); } k = k == 0 ? 1 : k; return findMedian(A, p + k, r, B, l, h - k); } else { int k = 0; if ((h - l + 1) % 2 == 0) { k = Math.min(medB - 1, r - medA - 1); } else { k = Math.min(medB, r - medA - 1); } k = k == 0 ? 1 : k; return findMedian(A, p, r - k, B, l + k, h); } } public static double findMedianBaseCase1(int med, int[] A, int p, int r) { if (r == p) { return (med + A[p]) / 2.0; } if (med == A[(r + p) / 2]) { return med; } else if (med < A[(r + p) / 2]) { if ((r - p + 1) % 2 == 0) { return A[(r + p) / 2]; } else { return (Math.max(med, A[(r + p) / 2 - 1]) + A[(r + p) / 2]) / 2.0; } } else {// if(med > A[(r+p)/2]) if ((r - p + 1) % 2 == 1) { return (A[(r + p) / 2] + Math.min(med, A[(r + p) / 2 + 1])) / 2.0; } else { return med < A[(r + p) / 2 + 1] ? med : A[(r + p) / 2 + 1]; } } } // med2 > med1 by default public static double findMedianBaseCase2(int med1, int med2, int[] A, int p, int r) { int medA = (r + p) / 2; if (r == p + 1) { if (med1 > A[p]) { if (med2 < A[r]) { return (med1 + med2) / 2.0; } else { return (med1 + A[r]) / 2.0; } } else if (med2 > A[r]) { return (A[r] + A[p]) / 2.0; } else { return (med2 + A[p]) / 2.0; } } if ((r - p + 1) % 2 == 0) { if (med2 < A[medA]) { return (Math.max(med2, A[medA - 1]) + A[medA]) / 2.0; } else if (med1 > A[medA]) { if (med2 < A[medA + 1]) { return (med1 + med2) / 2.0; } else {// med2 > A[medA+1] return (Math.min(med1, A[medA + 2]) + A[medA + 1]) / 2.0; } } else { return (A[medA] + Math.min(med2, A[medA + 1])) / 2.0; } } else { if (med1 > A[medA]) { return Math.min(A[medA + 1], med1); } else if (med2 < A[medA]) { return Math.max(med2, A[medA - 1]); } else { return A[medA]; } } } }
相关推荐
算法/编程练习:两个有序数组的中位数 题目来自LeetCode: https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 题目: 给定两个大小为 n1 和 n2 的有序(升序)数组 nums1 和 nums2 , 找出这两个有序...
无法登录两个有序数组的中位数 LeetCode 中“无重复字符的最长子串”问题的解决方法。 问题 有两个大小分别为 m 和 n 的排序数组 nums1 和 nums2。 找出两个已排序数组的中位数。 整体运行时间复杂度应该是 O(log (m...
leetcode04_寻找两个正序数组的中位数解法.rar !!!CSDN的一个特性: 即使我设置成免费下载,被下载的次数多了之后也会变成付C币下载的了,这个很头疼. !!!因此如果没有C币但想要下载的朋友可以在b站视频下留言给我,留下...
2、解题思路一开始没有理解题意,实际上,这道题目描述不够清楚基本题意如下:数组的下标,对应一个偏移量,表示下一步能够到达的下标举个例子输入:我们将每一个下标,都
4. 寻找两个有序数组的中位数给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O
在本压缩包“php-leetcode题解之合并两个有序数组.zip”中,主要涉及的是一个经典的算法问题——如何使用PHP解决LeetCode上的“合并两个有序数组”问题。这是一个常见的计算机科学与编程面试题目,旨在考察程序员...
2、解题思路 设置一个不重复位置指针,另一个向前移动,每一次都判断之前的是不是重复 如果重复,当前指针直接加一 不重复,将不重复指针加一,并将当前值复制过
标题中的“java-leetcode题解之第88题合并两个有序数组”指的是LeetCode平台上的一个编程挑战,问题编号为88,它涉及到如何合并两个已排序的整数数组,使得结果仍然保持有序。LeetCode是一个热门的在线编程练习平台...
在LeetCode刷题的过程中,我们经常会遇到一些挑战性的问题,其中“探寻两个有序数组中位数”就是一个典型的例子。这道题目属于数组类问题,它不仅要求我们理解数组的操作,更深层次地,它考察了我们对中位数概念的...
python python_leetcode题解之004两个排序数组的中位数
leetcode中国 LeetCode ...寻找两个有序数组的中位数 总结:求开方(牛顿迭代法)、查找区间、旋转数组查找数字 第 5 章 千奇百怪的排序算法 例题 215 数组中的第K个最大元素 347 前K个高频元素
- 从两个数组的末尾开始,比较两个数组中的元素大小,将较大的元素放入第一个数组的末尾。 - 使用三个指针分别指向两个数组的末尾和第一个数组的当前位置。 **数据结构**: 数组 **时间复杂度**: O(m+n),其中 m 和...
leetcode04_寻找两个正序数组的中位数解法.rar !!!CSDN的一个特性: 即使我设置成免费下载,被下载的次数多了之后也会变成付C币下载的了,这个很头疼. !!!因此如果没有C币但想要下载的朋友可以在b站视频下留言给我,留下...
python python_leetcode题解之026删除排序数组中的重复项
在本压缩包中,主题聚焦于C++编程基础与LeetCode算法题目的解析,特别是针对LeetCode中的第四题——寻找两个正序数组的中位数。这是一个经典的算法问题,旨在锻炼程序员对数组处理和排序算法的理解。下面我们将深入...
在这个问题中,我们可以初始化两个指针,i指向数组的起始位置,j指向数组的末尾。如果i处的元素等于j处的元素,那么我们将两个指针都向中间移动一位,即i++,j--。这是因为有序数组中相同元素相邻,我们要寻找的是...
在本压缩包中,我们关注的是Java编程语言与LeetCode平台上的第215题——“数组中的第K个最大元素”。LeetCode是一个在线的算法练习平台,它提供了丰富的编程题目来帮助程序员提升算法和数据结构技能。第215题是其中...
解决此问题的关键在于如何有效地找到两个有序数组的中位数,而无需实际合并它们,因为合并操作的时间复杂度为O(n + m),可能会导致效率低下。一种高效的策略是采用二分查找法,其时间复杂度可以达到O(log(min(n, m))...