lc 第四题 findMedianSortedArrays 寻找两个正序数组的中位数

算法的时间复杂度应该为 O(log (m+n)) 

如何分析时间复杂度  https://blog.csdn.net/qq_41523096/article/details/82142747

T(n) = 5logn,执行次数是对数的。

void eat2(int n){
   for(int i=1; i<n; i*=2){
       System.out.println("等待一天");
       System.out.println("等待一天");
       System.out.println("等待一天");
       System.out.println("等待一天");
       System.out.println("吃一半面包");
   }
}

典型的logn 就是二分查找

O(logn)的本质:输入规模翻倍,操作次数只增加一

考虑问题不全面 应该先考虑到其中一个数组为空的情况

其次没有考虑到nums2数组填完以后要将剩余的nums1的数字填进去 

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int temp[]=new int [nums1.length+nums2.length];
        int index=0;
        int interB;
        int interE=0;
        //1 2 4 5 和 2 3 7 9
        //右边2通过二分查找找到左边的相等或者小于最接近的x
        //将左边小于这个x的全部放进去
        //然后右边加一 
        //重复时 左边从上一个x1的位置到查到的x2的位置之间  
        if(nums2.length==0){
            temp=nums1;
        }else if(nums1.length==0){
            temp=nums2;
        }else{
            for(int j=0;j<nums2.length;j++){
                if(j==0){
                   interB=0;
                }else{
                interB=binarySearch(nums1,nums2[j-1]);
                }
                interE=binarySearch(nums1,nums2[j]);
                for(int i=interB;i<interE;i++){
                    temp[index]=nums1[i];
                    index++;
                }   
            temp[index]=nums2[j];
            index++;
            }
            for(int m=interE;m<nums1.length;m++){
                temp[index]=nums1[m];
                index++;
            }
        }
       
        if(temp.length%2==0){
            return (double)(temp[(temp.length-1)/2]+temp[(temp.length-1)/2+1])/2;
            
        }else{
            return temp[(temp.length-1)/2];
        }
    }

    public int binarySearch(int[] nums,int target){
        int left=0, right=nums.length-1;
        while(left<=right){
            int middle=left+(right-left)/2;
            if(nums[middle]>target){
                //在左边
                right=middle-1;
            }else if(nums[middle]<target){
                //在右边
                left=middle+1;
            }else{
                return middle;
            }  
        }
        return left;
    }
}

执行用时太多 虽然提交通过 还需改进算法。 

看到了log(m+n) 但是没有理解对 依然是使用二分查找来实现两个数组合并加排序

并不一定比直接合并加快排来的块

新解法 

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
       //num1为较短数组
       if(nums1.length>nums2.length){
           int temp[] =nums1;
           nums1=nums2;
           nums2=temp;
       }
        
       //条件一 左边的数和右边的数相等或者多一个中位数
       int m=nums1.length;
       int n=nums2.length;
       int totalLeft=(m+n+1)/2;
       //这条线左边的数的个数为(m+n+1)/2
       //假定奇数数列的中位数归到左边 
       //计算出一个数列的中位数后用公式计算的出另一个数列的中位数
       
       
       int left=0;
       int right=m;

        //条件二
        //nums1[i-1]<=nums2[j]&&nums2[j-1]<n=ums1[i]
        //考虑没有达成的处理办法 给条件取反 
        //nums1[i-1]>nums2[j]||nums2[j-1]>nums1[i]
        //所以只处理一种情况就行
       
        while(left<right){
           int i=left+(right-left+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 nums1RightMin= i==m ? Integer.MAX_VALUE :nums1[i];
        int nums2LeftMax= j==0 ? Integer.MIN_VALUE :nums2[j-1];
        int nums2LeftMin= j==n ? Integer.MAX_VALUE :nums2[j];
       
        if((m+n)%2==0){
            return (double)(Math.max(nums1LeftMax,nums2LeftMax)+Math.min(nums1RightMin,nums2LeftMin))/2;
        }else{
            return Math.max(nums1LeftMax,nums2LeftMax);
        } 
       
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值