生成一个合并数组:
分别用两个指针从两个数组的首部开始遍历,将两指针所指向元素中较小的加入合并数组,并指向该元素的指针该指针向后移动
题目只要求中位数,因此将合并数组完全生成再找中位数固然可以,但也可以将数组合并到中位数的位置就停下来,后者能提前结束循环,但逻辑判断会复杂一些
求中位数:
中位数可能是一个数也可能是两个数的平均值,看到很多答案都用了比较复杂的分情况讨论
我用的方法是求出mid1和mid2两个位置,无论什么情况下都返回这两个位置数的平均值
如果是一个数,mid1会等于mid2,都指向最中间的数,平均值仍是自身,即中位数;
如果是两个数,mid1 + 1 = mid2,指向中间的两个数,求平均值就是中位数。
有空可以看下这个,O(logn)解法?https://leetcode.com/problems/median-of-two-sorted-arrays/discuss/2481/Share-my-O(log(min(mn)))-solution-with-explanation
/**
* 自己的代码
* 只找到中位数的位置就停下,情况稍微复杂一些,后面的判断多,但能省去把整个数组排完浪费的资源
*/
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int length = nums1.length + nums2.length;
int[] nums = new int[length];
int p1 = 0, p2 = 0, idx = 0, mid1 = (length - 1) / 2, mid2 = length / 2;
while (p1 < nums1.length && p2 < nums2.length && idx < mid2 + 1)
if (nums1[p1] > nums2[p2])
nums[idx++] = nums2[p2++];
else
nums[idx++] = nums1[p1++];
if (idx == mid2 + 1)
return (nums[mid1] + nums[mid2]) / 2.0;
if (p1 == nums1.length)
if (p1 + p2 <= mid1 || p1 == 0)
return (nums2[mid1 - p1] + nums2[mid2 - p1]) / 2.0;
else
return (nums[mid1] + nums2[mid2 - p1]) / 2.0;
else
if (p1 + p2 <= mid1 || p2 == 0)
return (nums1[mid1 - p2] + nums1[mid2 - p2]) / 2.0;
else
return (nums[mid1] + nums1[mid2 - p2]) / 2.0;
}
}
/**
* 把整个数组排完的做法,代码比较简洁
*/
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int length = nums1.length + nums2.length;
int[] nums = new int[length];
int p1 = 0, p2 = 0, idx = 0, mid1 = (length - 1) / 2, mid2 = length / 2;
while (p1 < nums1.length && p2 < nums2.length)
if (nums1[p1] > nums2[p2])
nums[idx++] = nums2[p2++];
else
nums[idx++] = nums1[p1++];
while (p1 < nums1.length)
nums[idx++] = nums1[p1++];
while (p2 < nums2.length)
nums[idx++] = nums2[p2++];
return (nums[mid1] + nums[mid2]) / 2.0;
}
}
本文介绍了一种优化的算法,用于在两个有序数组中寻找中位数,仅遍历到中位数位置,避免了完全合并数组。作者分享了两种方法,一种是找到中位数位置后立即停止,另一种是通过对比指针移动合并数组。讲解了如何利用mid1和mid2确定中位数,简化了逻辑判断。

204

被折叠的 条评论
为什么被折叠?



