4.兩個正序陣列中位數
阿新 • • 發佈:2021-10-29
/** * 給定兩個大小分別為 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; } }