leetcode 4. Median of Two Sorted Arrays

    xiaoxiao2021-03-25  61

    There are two sorted arrays nums1 and nums2 of size m and n respectively.

    Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

    Example 1:

    nums1 = [1, 3] nums2 = [2] The median is 2.0

    Example 2:

    nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5

    题意:

    两个已排好序的数组,找出中位数,长度为奇数则是中间那个数,偶数则是中间两个数的平均值,复杂度要求O(log (m+n))。

    思路:

    可以转换为求在两个已排好序的数组中找第k个数。

    设数列A元素个数为n,数列B元素个数为m,各自升序排序,求第k小元素

    取A[k / 2] B[k / 2] 比较,如果 A[k / 2] > B[k / 2] 那么,所求的元素必然不在B的前k / 2个元素中,因为a中比B[k / 2]小的少于k/2个。 于是可以将A或B数列的前k/2元素删去,求剩下两个数列的k-k/2小元素,于是得到了数据规模变小的同类问题,递归解决。 如果 k / 2 大于某数列个数,所求元素必然不在另一数列的前k / 2个元素中,同上操作就好。

    代码:

    public class Solution { public int findkth(int[] nums1,int []nums2,int pos1,int pos2,int k){ // if(pos1==0&&pos2==0) System.out.println("---begin---"); System.out.println("pos1:"+pos1+" pos2:"+pos2+" k:"+k); if(pos1>=nums1.length) return nums2[pos2+k-1]; if(pos2>=nums2.length) return nums1[pos1+k-1]; if(k==1){ if(nums1[pos1]<=nums2[pos2]) return nums1[pos1]; return nums2[pos2]; } int index1=pos1+(k>>1)-1,index2=pos2+(k>>1)-1; // System.out.println("index1:"+index1+" index2:"+index2); int val1=((index1>=nums1.length)?Integer.MAX_VALUE:nums1[index1]); int val2=(index2>=nums2.length)?Integer.MAX_VALUE:nums2[index2]; if(val1>=val2){ return findkth(nums1,nums2,pos1,pos2+(k>>1),k-(k>>1)); } else{ return findkth(nums1,nums2,pos1+(k>>1),pos2,k-(k>>1)); } } public double findMedianSortedArrays(int[] nums1, int[] nums2) { if(nums1.length+nums2.length==0) return 0; int k=(nums1.length+nums2.length+1)>>1; if(((nums1.length+nums2.length)&1)==1){ return findkth(nums1,nums2,0,0,k); } return (findkth(nums1,nums2,0,0,k)+findkth(nums1,nums2,0,0,k+1))/2.0; } }

    另外,如果 k / 2 大于某数列个数,设该数列还有num未比较,可以比较该数列最后一个与另外一个数列的第k-num个数,同样的道理谁大删除另外一边。这里要注意的是,第二个数组可能没有足够的个数,需要每次保证先分配小的。如数据

    2 3 4 5 6 1 找第4个数,如果第一个数组分配2个,第2个数组则没有2个可以分配

    这种方法会稍快一些,这题时间卡的严格,k/2可以写成k>>1来优化

    代码:

    public class Solution { public int findkth_pre(int[] nums1,int []nums2,int pos1,int pos2,int k){ if(pos1==nums1.length) return nums2[pos2+k-1]; if(pos2==nums2.length) return nums1[pos1+k-1]; if(k==1){ if(nums1[pos1]<=nums2[pos2]) return nums1[pos1]; return nums2[pos2]; } int index1,index2; //保证小的分配不超过长度 谁小先分配谁 if(nums1.length-pos1<nums2.length-pos2){ index1=pos1+(k>>1)-1; if(index1>=nums1.length) index1=nums1.length-1; index2=pos2+k-(index1-pos1+1)-1; } else{ index2=pos2+(k>>1)-1; if(index2>=nums2.length) index2=nums2.length-1; index1=pos1+k-(index2-pos2+1)-1; } if(nums1[index1]>nums2[index2]){ return findkth_pre(nums1,nums2,pos1,index2+1,k-(index2-pos2+1)); } else{ return findkth_pre(nums1,nums2,index1+1,pos2,k-(index1-pos1+1)); } } public double findMedianSortedArrays(int[] nums1, int[] nums2) { if(nums1.length+nums2.length==0) return 0; int k=(nums1.length+nums2.length+1)>>1; if(((nums1.length+nums2.length)&1)==1){ return findkth_pre(nums1,nums2,0,0,k); } return (findkth_pre(nums1,nums2,0,0,k)+findkth_pre(nums1,nums2,0,0,k+1))/2.0; } }

    转载请注明原文地址: https://ju.6miu.com/read-33605.html

    最新回复(0)