1. 程式人生 > 其它 >4.兩個正序陣列中位數

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;
    }
	
}