【LeetCode 4】寻找两个正序数组的中位数

思路及难点

寻找数组中第k小的数字

  在寻找第k小的数字时,每次删除k/2个数字,即下一次寻找第k/2个数字。将时间复杂度降低至O(log(k))。对于中位数来说,k=(m+n)/2,因此将时间复杂度降低到O(log(m+n))。

public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
    
    
		int m = nums1.length;
		int n = nums2.length;
		int k = (m+n) / 2;
		int kth = getKthEle(nums1, nums2, k + 1);
		if ((m+n) % 2 != 0)
			return kth;
		return (getKthEle(nums1, nums2, k) + kth) / 2.0;
	}
public static int getKthEle(int[] nums1, int[] nums2, int k)
	{
    
    
		int m = nums1.length;
		int n = nums2.length;
		int ret = Integer.MAX_VALUE;
		if (m + n >= k) // 第k个元素必须在数组中
		{
    
    
			int i = 0, j = 0, half; // pos of nums1, pos of nums2, half of k pos
			int ii = i, jj = j; // reserve the old value
			while (true)
			{
    
    
				half = k/2 - 1;
				ii = i;
				jj = j;
				if (ii == m)
					return nums2[jj+k-1];
				if (jj == n)
					return nums1[ii+k-1];
				if (k == 1)
					return nums1[ii] < nums2[jj] ? nums1[ii] : nums2[jj];
				i = i+half < m-1 ? i+half : m-1;
				j = j+half < n-1 ? j+half : n-1;
				boolean flag = false; //并非是末端情况
				if (nums1[i] <= nums2[j])
				{
    
    
					if (i == m-1)
						flag = true;
					i++; //表示数组i之前的数字都可以舍弃了
					j = jj; //回退到起始位置
				}
				else if (nums1[i] > nums2[j])
				{
    
    
					if (j == n-1)
						flag = true;
					j++;
					i = ii;
				}
				int min = half+1;
				//舍弃整个数组的条件是:i=m-1,且nums1[i] < nums2[j],否则舍弃一半
				if (flag)
					min = min < Math.min(m, n) ? min : Math.min(m, n); 
					// 应该舍弃一半的数据还是舍弃掉整个数组?
				k = k - min; 
			}
		}
		return ret;
	}

おすすめ

転載: blog.csdn.net/juttajry/article/details/121374584