4.两个正序数组中位数

/**
 * 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
 * 示例 1:
 * 输入:nums1 = [1,3], nums2 = [2]
 * 输出:2.00000
 * 解释:合并数组 = [1,2,3] ,中位数 2
 * 示例 2:

 * 输入:nums1 = [1,2], nums2 = [3,4]
 * 输出:2.50000
 * 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
 * 示例 3:

 * 输入:nums1 = [0,0], nums2 = [0,0]
 * 输出:0.00000
 * 示例 4:

 * 输入:nums1 = [], nums2 = [1]
 * 输出:1.00000
 * 示例 5:
 * 
 * 提示:
 * nums1.length == m
 * nums2.length == n
 * 0 <= m <= 1000
 * 0 <= n <= 1000
 * 1 <= m + n <= 2000
 * -106 <= nums1[i], nums2[i] <= 106


 * 输入:nums1 = [2], nums2 = []
 * 输出:2.00000
 * 力扣(LeetCode)https://leetcode-cn.com/problems/median-of-two-sorted-arrays
 * 
 */
public class FindMedianOrdered {
	
	
	public static void main(String[] args) {
		int[] nums1 = {3,5};
		 int[] nums2 = {1,2};
		double ret = findMedianSortedArrays2(nums1, nums2);
		System.out.println(ret);
	}

	
	/**
	 * 简单粗暴,先将两个数组合并,两个有序数组的合并也是归并排序中的一部分。然后根据奇数,还是偶数,返回中位数。
	 * 时间复杂度:遍历全部数组 (m+n)(m+n)
	 * 空间复杂度:开辟了一个数组,保存合并后的两个数组 O(m+n)O(m+n)
	 * 该解法并不算太优雅,但最容易理解
	 */
    public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
    	 int[] nums;
	    int m = nums1.length;
	    int n = nums2.length;
	    nums = new int[m + n];
	    if (m == 0) {
	        if (n % 2 == 0) {
	            return (nums2[n / 2 - 1] + nums2[n / 2]) / 2.0;
	        } else {

	            return nums2[n / 2];
	        }
	    }
	    if (n == 0) {
	        if (m % 2 == 0) {
	            return (nums1[m / 2 - 1] + nums1[m / 2]) / 2.0;
	        } else {
	            return nums1[m / 2];
	        }
	    }
	    int count=0,i=0,j=0;
	    nums = new int[m+n];
	    while(count!=(m+n)){
	    	if(i==m){
	    		while(j!=n){
	    			nums[count++] = nums2[j++];
	    		}
	    		break;
	    	}
	    	
	    	if(j==n){
	    		while(i!=m){
	    			nums[count++] = nums1[i++];
	    		}
	    		break;
	    	}
	    	
	    	if(nums1[i] < nums2[j]){
	    		nums[count++] = nums1[i++];
	    	} else {
	    		nums[count++] = nums2[j++];
	    	}
	    }
	    
	    if (count % 2 == 0) {
	        return (nums[count / 2 - 1] + nums[count / 2]) / 2.0;
	    } else {
	        return nums[count / 2];
	    }
    	 
    }
    
    /**
     * 
     * 时间复杂度:遍历 len/2+1 次,len=m+n,所以时间复杂度依旧是 O(m+n)O(m+n)。
     * 空间复杂度:我们申请了常数个变量,也就是 m,n,len,left,right,aCursor,bCursor 以及 i。总共 8 个变量,所以空间复杂度是 O(1)O(1)。

     */
    public static double findMedianSortedArrays2(int[] nums1, int[] nums2) {
    	int m = nums1.length;
    	int n = nums2.length;
    	int len = m+n;
    	int aCursor = 0, bCursor = 0;
    	int left = -1, right = -1;
    	for (int i=0;i<=len/2;i++) {
    		left = right;
    		if(aCursor<m && (bCursor>=n 
    				|| nums1[aCursor] < nums2[bCursor])){
    			right = nums1[aCursor++];
    		}else {
    			right = nums2[bCursor++];
    		}
    	}
    	if((len & 1) == 0)
    		return (left + right) / 2.0;
    	else
    		return right;
    }
	
}
posted @ 2021-10-29 17:21  it鱼说  阅读(94)  评论(0)    收藏  举报