004寻找两个正序数组的中位数

写在前面,参考的力扣官网题解的解法三,自己用画图的形式解析了这个解法

二分

一、java代码

/*
 * @lc app=leetcode.cn id=4 lang=java
 *
 * [4] 寻找两个正序数组的中位数
 */

// @lc code=start
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        //两个数组的长度确定m,n
        int length1=nums1.length,length2=nums2.length;
        //m+n
        int totalLength=length1+length2;
        //如果总长度为奇数
        if(totalLength%2==1){
            //中位下标
            int midIndex=totalLength/2;
            //找到的即为第k小的值
            double median=getKthElement(nums1,nums2,midIndex+1);
            return median;

        //如果总长度为偶数
        }else{

            //中位下标1,中位下标2
            int midIndex1=totalLength/2-1,midIndex2=totalLength/2;
            //分别找到中间的两个第k1小,第k2小的值,再求平均
            double median=(getKthElement(nums1,nums2,midIndex1+1)+getKthElement(nums1,nums2,midIndex2+1))/2.0;
            return median;
        }

    }

    public int getKthElement(int[] nums1,int[] nums2,int k){
//主要思路:找到第k小的元素
//那么就取pivot1=nums1[k/2-1]和pivot2=nums2[k/2-1]进行比较
//nums1中小于pivot1的原色有nums1[0,...,k/2-2]共计k/2-1个,nums2中同理
//这样pivot本身最大也只能是第k-1小的元素
//如果pivot=pivot1,那么nums1[0,...,k/2-1]都不可能是第k小的元素
//把这些元素删除,剩下的作为nums1数组
//如果pivot=pivot2,那么nums1[0,...,k/2-1]都不可能是第k小的元素
//把这些元素删除,剩下的作为nums2数组
//因为删除了一些元素,所以k的值要改变

        //两个数组的长度
        int length1=nums1.length,length2=nums2.length;
        //两个数组的下标
        int index1=0, index2=0;
        //第k小的元素
        int kthElement=0;

        while(true){

            //边界情况
            if(index1==length1){

                //下标
                return nums2[index2+k-1];
            }
            if(index2==length2){
                return nums1[index1+k-1];
            }

            //当k=1时,小的那个就是第k
            if(k==1){
                return Math.min(nums1[index1],nums2[index2]);
            }
            //正常情况
            int half=k/2;
            int newIndex1=Math.min(index1+half,length1)-1;
            int newIndex2=Math.min(index2+half,length2)-1;

            //比较两个数组对应位置的值
            int pivot1=nums1[newIndex1],pivot2=nums2[newIndex2];
            if(pivot1<=pivot2){
                k-=(newIndex1-index1+1);
                index1=newIndex1+1;
            }else{
                k-=(newIndex2-index2+1);
                index2=newIndex2+1;
            }
        }
    }


}
// @lc code=end

二、 下面从奇数和偶数两个部分来分析这个算法

1、 如果m+n为奇数(很简单)

2、 如果m+n为偶数(当成两个奇数的来求就好了)

posted @ 2020-08-05 20:34  阿狸狸爱吃饭  阅读(167)  评论(0编辑  收藏  举报