leetcode题解Java | 4. Median of Two Sorted Arrays

题目https://leetcode.com/problems/median-of-two-sorted-arrays/#/description

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)).

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
分析

这道题的难点在于实现如何才能简洁。这是个二次二分的题,开始我只想到在nums1中二分,找到数nums1[mid1]后,找在nums2中的位置,再判断是否找到。这样,就需要在nums1和nums2上同时二分,再加上越界的判断问题,实现起来就比较困难。

后来看了stellari 的solution,确实是很巧妙的方法,用特殊的方法表示了分隔符,把奇偶的情况合二为一,且巧妙地处理了数组越界。下面简述一个他的方法,如有什么不清楚的,请看原文链接

首先,可以把奇数和偶数的情况合二为一,如 [2 3 4 5 6],我们可以这样分隔[2 3 (4/4) 5 7]

设斜杠左右的索引为L,R,那么 L = (N-1)/2, R = N/2

A[mid] = (A[(N-1)/2] + A[N/2])/2

现在为了表示斜杠,我们在数字间插入#

A1: [# 1 # 2 # 3 # 4 # 5 #]    (N1 = 5, N1_positions = 11)

A2: [# 1 # 1 # 1 # 1 #]     (N2 = 4, N2_positions = 9)

可以推出index(L) = (CutPosition-1)/2, index(R) = (CutPosition)/2

如果A2的插入位是C2,那么C1 = N1 + N2 - k,所以只需要二分一个,另一个就能求到,时间复杂度为O(log(min(n1,n2))

L1 = A1[(C1-1)/2]; R1 = A1[C1/2];

L2 = A2[(C2-1)/2]; R2 = A2[C2/2];

L1为A1插入符左边的数,R1为A1插入符后边的数

并且它们需要满足

L1 <= R1 && L1 <= R2&& L2 <= R1 && L2 <= R2

Java实现:

public double findMedianSortedArrays(int[] nums1, int[] nums2)
	{
		int n1 = nums1.length;
		int n2 = nums2.length;
		if(n2>n1) return findMedianSortedArrays(nums2, nums1);
		if(n2==0) return (nums1[(n1-1)/2]+nums1[n1/2])/2.0;
		int lo=0, hi=n2*2;
		while(lo<=hi)
		{
			int mid2 = (lo+hi)/2;
			int mid1 = n1+n2-mid2;
			int l1 = (mid1==0)? Integer.MIN_VALUE: nums1[(mid1-1)/2];//处理数组越界的情况
			int r1 = (mid1==2*n1)? Integer.MAX_VALUE: nums1[mid1/2];
			int l2 = (mid2==0)? Integer.MIN_VALUE: nums2[(mid2-1)/2];
			int r2 = (mid2==2*n2)? Integer.MAX_VALUE: nums2[mid2/2];
			if(l1>r2)
				lo = mid2+1;
			else if(l2>r1)
				hi = mid2-1;
			else
				return ((double)Integer.max(l1, l2)+(double)Integer.min(r1, r2))/2;
		}
		return -1;
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值