求两个升序序列的中位数( 减治法)

简介: 题目:一个长度为L(L≥1)的升序序列S,处在第L/2(若为小数则去掉小数后加1)个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现有两个等长升序序列A和B,试实现一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。

题目:


一个长度为L(L≥1)的升序序列S,处在第L/2(若为小数则去掉小数后加1)个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现有两个等长升序序列A和B,试实现一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。


解题图解:





代码:

public class SearchMid {
    public static void main(String[] args) {
        int arr1[] = {11, 13, 15, 17, 19};
        int arr2[] = {2, 4, 6, 8, 20};
        System.out.println("中位数:"+searchMid(arr1, arr2, arr1.length - 1));
    }
    private static int searchMid(int[] arr1, int[] arr2, int n) {
        int start1 = 0, start2 = 0, end1 = n, end2 = n, mid1 = 0, mid2 = 0;
        while (end1 > start1 && end2 > start2) {
            mid1 = (start1 + end1) / 2;
            mid2 = (start2 + end2) / 2;
            if (arr1[mid1] == arr2[mid2]) {
                return arr1[mid1];
            }
            if (arr1[mid1] < arr2[mid2]) {
//                if ((end1-start1)%2==0){
//                    start1=mid1;
//                }
//                else{
//                    start1=mid1+1;
//                }
                start1 = (end1 - start1) % 2 == 0 ? mid1 : mid1 + 1;
                end2 = mid2;
            } else {
                end1 = mid1;
                start2 = (end2 - start2) % 2 == 0 ? mid2 : mid2 + 1;
//                if ((end2-start2)%2==0){
//                    start2=mid2;
//                }
//                else {
//                    start2=mid2+1;
//                }
            }
        }
        return arr1[start1] > arr2[start2] ? arr2[start2] : arr1[start1];
//        if (arr1[start1]>arr2[start2]){
//            return arr2[start2];
//        }
//        else  return arr1[start1];
    }
}
相关文章
|
5月前
|
弹性计算 网络协议
阿里云99元服务器——有问必答,你想知道的问题都在这!
阿里云99元服务器来了!ECS经济型e实例,2核2G、3M固定带宽、40G云盘,新老用户同享,续费仅99元/年,不限流量,独立IP,性能稳定。适用于建站、开发、测试等场景,活动持续至2027年
690 1
Node安装版本低于工程版本时打包绕过校验
在开发中,若本地Node版本低于项目配置要求,导致打包报错(如图所示),可在不变更本地环境的情况下,通过在执行`npm run build`前输入命令`set NODE_OPTIONS=--openssl-legacy-provider`来绕行此问题,确保构建顺利进行。
1038 10
|
JSON 安全 API
API接口是什么?(一篇文章全知道)
在数字化时代,API接口已成为推动软件生态和互联网创新的核心枢纽。本文深入解析了API的本质、架构、类型及应用场景,展示了其在移动互联网、电商、智慧城市等领域的广泛应用,并探讨了API在经济、创新和效率方面的巨大价值与深远影响。
4760 2
|
Python
递归魔法:判断字符串是否为回文
本文介绍了如何使用递归判断一个字符串是否是回文。回文字符串是指正读和反读都相同的字符串。文章详细讲解了递归的基本思想和Python实现,并通过多个示例验证了函数的正确性。递归方法通过将大问题分解成更小的子问题,使得判断回文变得简单高效。
560 5
|
算法 物联网 定位技术
智慧停车场导航:高精度3D建模与实时数据驱动的停车解决方案
随着城市车辆数量的激增,传统停车场面临着管理效率低下、停车难、寻车难等问题。智慧停车场导航停车和反向寻车技术的引入,为解决这些问题提供了创新方案,极大提升了停车场的智能化水平和用户体验。
952 21
智慧停车场导航:高精度3D建模与实时数据驱动的停车解决方案
|
Ubuntu 开发工具 git
Git高手必备:掌握这些版本控制最佳实践,让你的代码管理效率翻倍!
【10月更文挑战第25天】使用 Git 进行版本控制是现代软件开发的重要部分。本文详细介绍了 Git 的安装、配置、基本操作、分支管理、冲突解决及常用命令,帮助开发者提高工作效率,确保代码质量和团队协作的顺利进行。通过合理使用 Git,可以有效管理代码变更,支持多人协作,并追踪历史记录。
856 4
|
运维 jenkins 持续交付
自动化运维之路:构建高效CI/CD流水线
在软件开发的快节奏中,持续集成和持续部署(CI/CD)流水线是提升效率、保障质量的关键。本文将引导你理解CI/CD流水线的重要性,并手把手教你如何搭建一个高效的自动化运维系统。通过实际代码示例,我们将一步步实现从代码提交到自动测试、部署的全流程自动化,确保软件交付过程既快速又可靠。
1096 5
|
网络协议 安全 网络安全
DDoS有什么有效预防措施
抵御DDoS攻击的方法包括:使用高性能网络设备和硬件防火墙;避免NAT以保持通信效率;确保充足网络带宽;升级服务器硬件;采用静态或伪静态网页;增强OS的TCP/IP栈;安装专业防火墙;备份网站并使用CDN。考虑云服务商的高防IP服务以提升防护级别。综合应用这些策略可有效防止DDoS攻击。
2154 1
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的电影院购票系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的电影院购票系统的详细设计和实现(源码+lw+部署文档+讲解等)
294 1
|
存储 安全 网络安全
服务器设置了端口映射之后外网还是访问不了服务器
服务器设置了端口映射之后外网还是访问不了服务器