两数组中位数

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++;
            }
            //清理剩余的
            //中位数的位置在nums1
            if(i<nums1.length)
                return (nums1[i+mid-1-k]+nums1[i+mid-k])/2.0;
            //中位数的位置在nums2
            else
                return (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++;
            }
            //清理剩余的
            //中位数的位置在nums1
            if(i<nums1.length)
                return nums1[i+midindex-k];
            else
                return nums2[j+midindex-k];
        }
    }

解法(三)

通过递归跳跃实现寻找中位数,首先计算出中位数要跳跃的距离,然后根据距离每次折半进行跳跃,从而渐渐逼近中位数。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        //计算中位数位置,如果m+n等于奇数的话left==right
        int 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);
        }        
    }
}
posted @   鸭梨的药丸哥  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示