两数组中位数
leetcode 4----兩數組中位數
解法(一)
通過新建數組的辦法,將兩個數組合并成一個,然后找中位數,代碼容易理解,但不是很快并且有點浪費空間。
public double findMedianSortedArrays(int[] nums1, int[] nums2) {int len = nums1.length+nums2.length;int i = 0,j = 0,k=0;while(i<nums1.length && j<nums2.length){if(nums1[i]<=nums2[j]) arr[k++] = nums1[i++];else arr[k++] = nums2[j++];}while(i<nums1.length) arr[k++] = nums1[i++];while(j<nums2.length) arr[k++] = nums2[j++];if(len%2 == 0){int mid =len/2;return (arr[mid-1]+arr[mid])/2.0;}else{double mid = len/2.0;return (double)arr[(int)Math.ceil(mid)-1];}}解法(二)
首先計算中位數,然后兩數組一個一個比較,并統計比較個數,當比較個數到中位數位置,直接獲取中位數的數數據,然后進行計算。
//計算中位數public double getmidnumber(int[] nums1, int[] nums2,int i,int j){int result = 0;//再判斷兩次即可if(nums1[i]<=nums2[j]) result += nums1[i++]; else result += nums2[j++];if(i<nums1.length && j<nums2.length){if(nums1[i]<=nums2[j]) result += nums1[i++]; else result += nums2[j++];return result/2.0;}if(i<nums1.length) {result += nums1[i++]; return result/2.0;}if(j<nums2.length) {result += nums2[j++]; return result/2.0;}return result/2.0;}public double findMedianSortedArrays(int[] nums1, int[] nums2) {int len = nums1.length+nums2.length;int i = 0,j = 0,k=0;//判斷長度是奇數還是偶數if(len%2 == 0){int mid =len/2;//中位數在分別兩個數組while(i<nums1.length && j<nums2.length){//到達中位數的下標if(k == mid-1)return getmidnumber(nums1,nums2,i,j);//根據大小移動if(nums1[i]<=nums2[j]) i++;else j++;k++;}//清理剩余的//中位數的位置在nums1if(i<nums1.length)return (nums1[i+mid-1-k]+nums1[i+mid-k])/2.0;//中位數的位置在nums2elsereturn (nums2[j+mid-1-k]+nums2[j+mid-k])/2.0;}else{//奇數直接除二就能拿到那個中位數下標int midindex = len/2;//中位數在分別兩個數組while(i<nums1.length && j<nums2.length){//到達中位數的下標if(k == midindex)return nums1[i]<nums2[j]?nums1[i]:nums2[j];//根據大小移動if(nums1[i]<=nums2[j]) i++;else j++;k++;}//清理剩余的//中位數的位置在nums1if(i<nums1.length)return nums1[i+midindex-k];elsereturn nums2[j+midindex-k];}}解法(三)
通過遞歸跳躍實現尋找中位數,首先計算出中位數要跳躍的距離,然后根據距離每次折半進行跳躍,從而漸漸逼近中位數。
public double findMedianSortedArrays(int[] nums1, int[] nums2) {int m = nums1.length;int n = nums2.length;//計算中位數位置,如果m+n等于奇數的話left==rightint left = (m + n + 1) / 2;int right = (m + n + 2) / 2;return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;}//i: nums1的起始位置 j: nums2的起始位置//k: 是距離public int findKth(int[] nums1, int i, int[] nums2, int j, int k){if( i >= nums1.length) return nums2[j + k - 1];//nums1為空數組if( j >= nums2.length) return nums1[i + k - 1];//nums2為空數組//到達位置后,判斷if(k == 1){return Math.min(nums1[i], nums2[j]);}//跳躍,如果越界,用int的最大值表示無法進行跳躍int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;//判斷往哪邊進行跳躍,并縮短跳躍距離,漸漸逼近中位數//往小的方向進行跳躍,這樣可以避免跳過中位數的情況if(midVal1 < midVal2){return findKth(nums1, i + k / 2, nums2, j , k - k / 2);}else{return findKth(nums1, i, nums2, j + k / 2 , k - k / 2);} } }總結
- 上一篇: 使用Socket模拟聊天室
- 下一篇: HashMap解析