• 算法总结之 在两个长度相等的排序数组中找到上中位数


    题目描述: arr1  和 arr2   长度都为N   求两个数组中所有数的上中位数

    要求 时间复杂度 O(logN)  额外空间复杂度O(1)

    这道题目的方法比较好玩:

       这两个数组如下表示:

     arr1[start1....end1]     arr2[start2...end2]

    如果start1==start2  那么也有start2==end2   此时元素总个数是2个,上中位数为最小的那个  

    如果start1!=start2  令mid1={start1+end1}/2      mid1={start2+end2}/2

         进而分情况

                                 情况一、 如果arr1[mid1] == arr2[mid2]

                                                        如果两个数组长度为奇数或者偶数,那么arr1[mid1] == arr2[mid2]=上中位数

                                 情况二、如果arr1[mid1] >arr2[mid2]

                                                       如果长度为奇数、(假设为5)arr1的第三个数>arr2的第三个数  此时上中位数只能是从arr1的{1,2,3}和arr2的{3,4,5}的共同的上中位数找 

                                                       如果长度为偶数,(假设为4)arr1的第二个数>arr2的第二个数  此时上中位数只能是从arr1的{1,2}和arr2的{3,4}的共同的上中位数找 

                                              如果arr1[mid1] <arr2[mid2]情况完全一致  请读者自行推理

    代码实现是这样:

      特别类似于二分查找 哈哈  也是找mid 然后通过min去比较

         其实两个数组长度是一致的  某种程度上说是当前数组的影子 或者 映射吧 都是有关联的 所以重点操作一个数组 然后通过某种关系去映射另外一个数组就OK了

        比较两个数组mid的值 决定两个数组 后面遍历的走向

    废话不多说,上代码:

    package TT;
    
    public class Test12 {
    
        public  static int getUpMedian(int[] arr1 , int[] arr2){
            
            if(arr1==null || arr2==null || arr1.length != arr2.length){
                throw new RuntimeException("hi,babay.are you ok?");
            }
            
            int start1 =0;
            int end1 = arr1.length-1;
            
            int start2=0;
            int end2 = arr2.length-1;
            
            int mid1 =0;
            int mid2 =0;
            
            int offset = 0;
    
            while(start1 < end1){
                mid1 = (start1+end1)/2;
                mid2 = (start2+end2)/2;
                //元素个数如果是奇数为0 偶数为1
                offset = ((end1 - start1+1)&1)^1;
                if(arr1[mid1] > arr2[mid2]){
                    end1 = mid1;
                    start2=mid2+offset;
                }else if(arr1[mid1]<arr2[mid2]){
                    start1 = mid1 + offset;
                    end2 = mid2;
                
                }else {
                    return arr1[mid1];
                }            
            }
            
            return Math.min(arr1[start1], arr2[start2]);   
        }
        
        public static void main(String[] args){
            
               int[] a1 = new int[4];
               int[] a2 = new int[4];
               
              a1[0]=0;  a1[1]=1;  a1[2]=2; a1[3]=3;
              a2[0]=4;  a2[1]=5;  a2[2]=5; a2[3]=6;
    
              int c = getUpMedian(a1,a2);
              
              System.out.println(c);
            
            
        }
         
    }

    结果:

    手写实现很多思路,我觉得这样写是最清晰明了的

    public class Test4 {
        public static int getMidValue(int[] arr1, int[] arr2) {
            // 参数验证
            if (arr1 == null || arr2 == null || arr1.length != arr2.length) {
                throw new RuntimeException("请检查参数");
            }
            // 执行业务逻辑 (左右指针)
            int start1 = 0;
            int end1 = arr1.length - 1;
    
            int start2 = 0;
            int end2 = arr2.length - 1;
    
            while (start1 < end1) {
                int mid1 = (end1 - start1) / 2;
                int mid2 = (end2 - start2) / 2;
                // 移动的开关 (元素个数奇数偶数判断取决于 移动与否)
                int offset = (end1-start1+1)%2  == 0 ? 1 : 0;    //时刻判断
                if (arr1[mid1] > arr2[mid2]) {
                    end1 = mid1;
                    start2 = mid2 + offset;
                } else if (arr1[mid1] < arr2[mid2]) {
                    end2 = mid2;
                    start1 = mid1 + offset;
                } // 如果相等的话就直接返回了
                return Math.min(arr1[start1], arr2[start1]);
    
            }
    
            return Math.min(arr1[start1], arr2[start1]);
        }
    
        public static void main(String[] args) {
            int[] arr1 = { 1, 3, 5, 7 };
            int[] arr2 = { 2, 4, 6, 8 };
            int midValue = getMidValue(arr1, arr2);
            System.out.println(midValue);
        }
    }
  • 相关阅读:
    IDEA忽略某些文件
    Mac操作:Mac系统移动鼠标显示桌面(移动鼠标到角落)
    Mac流程图的软件
    Mac 电脑无法登陆 账号了
    学习如何管理-录视频
    项目倒入maven 遇到的问题只有 main 了
    下载代码的时候 SSH与http的区别
    Mac修改hosts方法
    MAC版本的UltraEdit破解方法
    intelliJ 社区版-找不到 plugins选项
  • 原文地址:https://www.cnblogs.com/toov5/p/7417084.html
Copyright © 2020-2023  润新知