找第K位小数 O(log(m+n))

 public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;

        int k1 = (len1 + len2 + 1) / 2;
        int k2 = (len1 + len2 + 2) / 2;
        return (getKth(nums1, 0, len1 - 1, nums2, 0, len2 - 1, k1)
                + getKth(nums1, 0, len1 - 1, nums2, 0, len2 - 1, k2)) * 0.5;
}
private static int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
        int len1 = end1 - start1 + 1;
        int len2 = end2 - start2 + 1;

        //方便K=1时,返回结果
        if(len1 > len2){
            return getKth(nums2,start2,end2,nums1,start1,end1,k);
        }
        //num1空了,只要动nums2就行
        if(len1 == 0) return nums2[start2 + k - 1];

        if(k==1) return Math.min(nums1[start1],nums2[start2]);

        int i = start1 + Math.min(len1, k / 2) - 1;
        int j = start2 + Math.min(len2, k / 2) - 1;
        if(nums1[i] > nums2[j]){
            return getKth(nums1,start1,end1,nums2,j+1,end2,k - (j - start2 + 1));
        }else{
            return getKth(nums1,i+1,end1,nums2,start2,end2,k - (i - start1 + 1));
        }
    }

划分数组,两分法 O(log(min(m,n))

    public static double findMedianSortedArrays2(int[] nums1, int[] nums2) {

        if (nums1.length > nums2.length) {
            int[] temp = nums1;
            nums1 = nums2;
            nums2 = temp;
        }
        int n = nums1.length;
        int m = nums2.length;

        //得到左部分长度,向上取整,奇数多一个
        int totalLeft =  (n + m + 1) / 2;

        // 在 nums1 的区间 [0, n] 里查找恰当的分割线,
        // 使得 nums1[i - 1] <= nums2[j] && nums2[j - 1] <= nums1[i],等价于nums[0,n]中找到最大的i
        int left = 0;
        int right= n;

        while(left < right){
            int i = (left + right + 1) /2;
            int j = totalLeft - i;

            if(nums1[i-1] > nums2[j]){
                //左移
                right = i-1;
            }else{
                //右移
                left  = i;
            }
        }

        int i = left;
        int j = totalLeft - i;

        int nums1LeftMax = i==0?Integer.MIN_VALUE:nums1[i-1];
        int nums2LeftMax = j==0?Integer.MIN_VALUE:nums2[j-1];

        int nums1RightMin= i==n?Integer.MAX_VALUE:nums1[i];
        int nums2RightMin= j==m?Integer.MAX_VALUE:nums2[j];

        if((n+m%2)==1){
            return Math.max(nums1LeftMax,nums2LeftMax);
        }else{
            return (double)(Math.max(nums1LeftMax,nums2LeftMax) + Math.min(nums1RightMin,nums2RightMin)) /2;
        }

    }