• 困难4. 寻找两个正序数组的中位数


    这题难了我几天,重写了几遍代码,一直感觉不对,算法复杂度没降下来,直到今天10月7日完成
    ### 解题思路
    不停判断区间1是否相交区间2
    假如中位数存在num1中,不停地对nums1取中间值,在nums2中找,直到找到为止
    假如找不到,那么最后区间1和区间2不会相交
     
    执行结果:通过
    执行用时:168 ms, 在所有 JavaScript 提交中击败了11.10%的用户
    内存消耗:50.8 MB, 在所有 JavaScript 提交中击败了10.32%的用户
    通过测试用例:2094 / 2094
     

    给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

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

    示例 1:

    输入:nums1 = [1,3], nums2 = [2]
    输出:2.00000
    解释:合并数组 = [1,2,3] ,中位数 2
    示例 2:

    输入:nums1 = [1,2], nums2 = [3,4]
    输出:2.50000
    解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
     

    提示:

    nums1.length == m
    nums2.length == n
    0 <= m <= 1000
    0 <= n <= 1000
    1 <= m + n <= 2000
    -106 <= nums1[i], nums2[i] <= 106

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/median-of-two-sorted-arrays
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    /**
     * @param {number[]} nums1
     * @param {number[]} nums2
     * @return {number}
     */
    var findMedianSortedArrays = function(nums1, nums2) {
       //例如:求一个考生在全国的排名p,分数为num
        //先用二分法求考生在各省的排名p1、p2...pn
        //分数num在全国的排名p=p1+p2+..+pn
    
        //如果中位数比排名p大,以当前考生为最左边,继续上一步的查找
        //如果中位数比排名p小,以当前考生为最右边,继续上一步的查找
        //如果中位值等于排名p,那这个考生就是全国排名的中位数
        let l1=0,r1=nums1.length;
        let l2=0,r2=nums2.length;
        let isLock=true;
        let len=nums1.length+nums2.length
        const isTwo=len%2===0
        const needMid=len>>1
        let ans1
        let ans2
        while(isLock){
            console.log(l1,r1,l2,r2)
             //区间有交叉
            if(l1===r1||nums1[r1-1]<=nums2[l2]){
                isLock=false
                if(r1>needMid-l2){
                    ans1=nums1[needMid-l2]
                }else{
                    ans1=nums2[needMid-r1]
                }
                if(r1>needMid-1-l2){
                    ans2=nums1[needMid-1-l2]
                }else{
                    ans2=nums2[needMid-r1-1]
                }
                console.log(ans1,ans2)
                
            }else if(l2===r2||nums2[r2-1]<=nums1[l1]){
                isLock=false
                if(r2>needMid-l1){
                    ans1=nums2[needMid-l1]
                }else{
                    ans1=nums1[needMid-r2]
                }
                if(r2>needMid-1-l1){
                        ans2=nums2[needMid-l1-1]
                    }else{
                        ans2=nums1[needMid-r2-1]
                    }
                    console.log(ans1,ans2)
            }else{
                const mid=(l1+r1)>>1
                //获取排名
                const [p1,p2]=getScope(nums1[mid],nums2,l2,r2);
                
                if(mid+p1>needMid){
                    r1=mid
                    r2=p1
                }else if(mid+p2<needMid){
                    l1=mid
                    l2=p2
                }else{
                    isLock=false
                    
                    //在nums1中找到
                    ans1=nums1[mid]
                    if(needMid-mid>0&&mid>0){
                        ans2=Math.max(nums1[mid-1],nums2[needMid-mid-1])
                    }else if(mid>0){
                        ans2=nums1[mid-1]
                    }else{
                        ans2=nums2[needMid-mid-1]
                    }
                }
            }
           
        }
        
        console.log(l1,r1,l2,r2,needMid)
        if(isTwo){
            return (ans1+ans2)/2
        }
        return ans1
        
        //获取数字在数组中的区域[左边,右边]
        function getScope(num,arr,l,r){
            let lock=true
            while(lock&&l<r){
                const m=(l+r)>>1
                if(arr[m]>num){
                    r=Math.min(m,r-1);
                }else if(arr[m]<num){
                    l=Math.max(m,l+1);
                }else{
                    l=m;
                    r=m+1;
                    while(arr[l-1]===arr[m]){
                        l--
                    }
                    while(arr[r]===arr[m]){
                        r++
                    }
                    lock=false;
                }
            }
            return [l,r];
        }
        
    };
  • 相关阅读:
    [计算机视觉]算法
    [python]python中**是什么
    ubuntu16.04增大swap空间
    conda查看某个安装包的依赖项
    conda install -c anaconda
    conda安装指定版本的指定包
    ValueError: Unable to determine SOCKS version from socks://127.0.0.1:1080/
    [ubuntu]卸载老版并安装最新版firefox
    使用anaconda创建tensorflow环境后如何在jupyter notebook中使用
    [python]numpy.mean()用法
  • 原文地址:https://www.cnblogs.com/caoke/p/16767464.html
Copyright © 2020-2023  润新知