LeedCode刷题系列0004——两个排序数组的中位数

7 篇文章 0 订阅
5 篇文章 0 订阅

 

问题:

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 

请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。

你可以假设 nums1 和 nums2 不同时为空。


测试用例:

示例 1:

nums1 = [1, 3]
nums2 = [2]

中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

中位数是 (2 + 3)/2 = 2.5

解决方案:

考虑将两个有序数组nums1 和 nums2先合并成一个有序数组nums3,在直接区中位数

此方法比较简单,时间复杂度为O(log (m+n))。

另附官方解答方案

下面是两种方法比较的java代码

package com.lmm.LeedCode;

/**
 * @author lmm E-mail:violet_mmhh@163.com
 * @version 时间:2018年10月23日
 * @question 给定一个字符串,找出不含有重复字符的最长子串的长度。
 */
public class Solution0004 {
	// 我的解答:先合并数组再去中位数
	public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
		int a = nums1.length;
		int b = nums2.length;
		int i = 0, j = 0, k = 0;
		int[] nums3 = new int[a + b];

		if (a == 0) {
			nums3 = nums2;
		}
		if (b == 0) {
			nums3 = nums1;
		}
		while (i < nums1.length && j < nums2.length) {
			if (nums1[i] <= nums2[j])
				nums3[k++] = nums1[i++];
			else
				nums3[k++] = nums2[j++];
		}
		while (i < nums1.length) {
			nums3[k++] = nums1[i++];
		}
		while (j < nums2.length) {
			nums3[k++] = nums2[j++];
		}

		if ((a + b) % 2 == 0) {
			int c = (a + b) / 2;
			return (nums3[c - 1] + nums3[c]) * 1.0 / 2;
		} else {
			int c = (a + b) / 2;
			return nums3[c] * 1.0;
		}
	}

	// 官方解答:递归法
	public static double findMedianSortedArrays2(int[] A, int[] B) {
		int m = A.length;
		int n = B.length;
		if (m > n) { // to ensure m<=n
			int[] temp = A;
			A = B;
			B = temp;
			int tmp = m;
			m = n;
			n = tmp;
		}
		int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
		while (iMin <= iMax) {
			int i = (iMin + iMax) / 2;
			int j = halfLen - i;
			if (i < iMax && B[j - 1] > A[i]) {
				iMin = i + 1; // i is too small
			} else if (i > iMin && A[i - 1] > B[j]) {
				iMax = i - 1; // i is too big
			} else { // i is perfect
				int maxLeft = 0;
				if (i == 0) {
					maxLeft = B[j - 1];
				} else if (j == 0) {
					maxLeft = A[i - 1];
				} else {
					maxLeft = Math.max(A[i - 1], B[j - 1]);
				}
				if ((m + n) % 2 == 1) {
					return maxLeft;
				}

				int minRight = 0;
				if (i == m) {
					minRight = B[j];
				} else if (j == n) {
					minRight = A[i];
				} else {
					minRight = Math.min(B[j], A[i]);
				}

				return (maxLeft + minRight) / 2.0;
			}
		}
		return 0.0;
	}

	public static void main(String[] args) {
		int[] nums1 = { 1, 3 };
		int[] nums2 = { 2, 4 };
		long startTime = System.nanoTime();
		System.out.println(findMedianSortedArrays(nums1, nums2));
		long endTime = System.nanoTime(); // 获取结束时间
		System.out.println("我的解答时间: " + (endTime - startTime) + "ns");
		long startTime2 = System.nanoTime();
		System.out.println(findMedianSortedArrays2(nums1, nums2));
		long endTime2 = System.nanoTime(); // 获取结束时间
		System.out.println("官方解答时间: " + (endTime2 - startTime2) + "ns");
	}

}

 

运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值