算法:两个数组取中位数

2023-11-07

要求:任意两个数组取中位数,在保证空间复杂度的同时,时间复杂度要求log(m + n)

 

package com.flash.hance;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: lizheng
 */
public class Test {


    /**
     * 查找中位数
     * @param nums1
     * @param nums2
     * @return
     */
    public Double findMedianSortedArrays(int[] nums1, int[] nums2) {
        Middle middle = new Middle(0, nums1.length + nums2.length);
        String string = "";
        string.toCharArray();
        // 1.空数组判断
        if (nums1.length == 0) {
            return (nums2[middle.getFirstFlag()] + nums2[middle.getSecondFlag()]) / 2D;
        }
        if (nums2.length == 0) {
            return (nums1[middle.getFirstFlag()] + nums1[middle.getSecondFlag()]) / 2D;
        }
        NumsData numsData1 = new NumsData(nums1);
        NumsData numsData2 = new NumsData(nums2);
        // 具体的查找动作
        return doFindMedian(numsData1, numsData2, middle);
    }

    /**
     *
     * @param nums1
     * @param nums2
     * @param middle
     * @return
     */
    public Double doFindMedian(NumsData nums1, NumsData nums2, Middle middle) {
        int length = nums1.getLength() + nums2.getLength();
        // 1.小数组采用排序法处理
        if (length <= 4) {
            // 数组排序并打印
            return culBySort(nums1, nums2, middle);
        }
        // 2.获取两个数组的中位数
        Middle middle4Nums1 = new Middle(0, nums1.getLength());
        Integer nums1SecondData = nums1.getByIndex(middle4Nums1.getSecondFlag());
        Middle middle4Nums2 = new Middle(0, nums2.getLength());
        Integer nums2SecondData = nums2.getByIndex(middle4Nums2.getSecondFlag());
        if (nums1SecondData >= nums2SecondData) {
            // 取第一个数组的后半部分;第二数组的前半部分
            nums1.setRightOffset(middle4Nums1.getSecondFlag());
            nums2.setLeftOffset(middle4Nums2.getSecondFlag());
        } else {
            // 取第一数组的前半部分;第二个数组的后半部分
            nums1.setLeftOffset(middle4Nums1.getSecondFlag());
            nums2.setRightOffset(middle4Nums2.getSecondFlag());
        }

        return doFindMedian(nums1, nums2, middle);
    }

    /**
     * 通过数组排序的方法计算中值
     * @param nums1
     * @param nums2
     * @return
     */
    public Double culBySort(NumsData nums1, NumsData nums2, Middle middle) {
        List<Integer> list = new ArrayList<Integer>();
        Integer nu2Flag = 0;
        // 数组排序
        for (int i = 0; i < nums1.getLength(); i++) {
            for (int j = nu2Flag; j < nums2.getLength(); j++) {
                if (nums1.getByIndex(i) < nums2.getByIndex(j)) {
                    list.add(nums1.getByIndex(i));
                    break;
                } else if (nums1.getByIndex(i) == nums2.getByIndex(j)) {
                    list.add(nums1.getByIndex(i));
                    list.add(nums2.getByIndex(j));
                    nu2Flag = nu2Flag < j + 1 ? j + 1 : nu2Flag;
                    break;
                } else {
                    nu2Flag = nu2Flag < j + 1 ? j + 1 : nu2Flag;
                    list.add(nums2.getByIndex(j));
                }
            }
        }
        if (nu2Flag < nums2.getLength()) {
            for (int i = nu2Flag; i < nums2.getLength(); i++) {
                list.add(nums2.getByIndex(i));
            }
        }
        // 取中值
        int leftOffset = nums1.getLeftOffset() + nums2.getLeftOffset();
        return (list.get(middle.getFirstFlag() - leftOffset) + list.get(middle.getSecondFlag() - leftOffset)) / 2D;
    }

    public static void main(String[] args) {
        Test test = new Test();
//        int[] nums1 = {0, 1,2};
//        int[] nums2 = {};

//        int[] nums1 = {0, 1,2};
//        int[] nums2 = {3, 4, 5};

//        int[] nums1 = {0, 1,2};
//        int[] nums2 = {3};

//        int[] nums1 = {0, 1,3};
//        int[] nums2 = {2};

//        int[] nums1 = {0, 1, 2, 7, 8};
//        int[] nums2 = {3,4,5,6};

        int[] nums1 = {1, 2};
        int[] nums2 = {-1, 3};
        double result = test.findMedianSortedArrays(nums1, nums2);
        System.out.println(result);
    }

}

/**
 * 数据包装对象:
 * 提供getLength、getIndex方法,对外屏蔽掉偏移量
 */
class NumsData {
    int[] data;
    int leftOffset;
    int rightOffset;

    public NumsData(int[] data) {
        this.data = data;
        this.leftOffset = 0;
        this.rightOffset = 0;
    }

    public NumsData(int[] data, int leftOffset, int rightOffset) {
        this.data = data;
        this.leftOffset = leftOffset;
        this.rightOffset = rightOffset;
    }

    public int[] getData() {
        return data;
    }

    public void setData(int[] data) {
        this.data = data;
    }

    public int getLeftOffset() {
        return leftOffset;
    }

    public void setLeftOffset(int leftOffset) {
        this.leftOffset += leftOffset;
    }

    public int getRightOffset() {
        return rightOffset;
    }

    public void setRightOffset(int rightOffset) {
        this.rightOffset += rightOffset;
    }

    public Integer getLength() {
        return data.length - leftOffset - rightOffset;
    }

    public Integer getByIndex(Integer index) {
        return data[index + leftOffset];
    }
}

/**
 * 中位数坐标
 */
class Middle {
    private Integer firstFlag;  // 中位数所处坐标,从0开始
    private Integer secondFlag; // 中位数所处坐标,从0开始

    public Middle(Integer length1, Integer length2) {
        int length = length1 + length2;
        int mod = length % 2;
        if (mod == 0) {
            secondFlag = length >> 1;
            firstFlag = secondFlag - 1;
        } else {
            firstFlag = secondFlag = length >> 1;
        }
    }

    public Integer getFirstFlag() {
        return firstFlag;
    }

    public void setFirstFlag(Integer firstFlag) {
        this.firstFlag = firstFlag;
    }

    public Integer getSecondFlag() {
        return secondFlag;
    }

    public void setSecondFlag(Integer secondFlag) {
        this.secondFlag = secondFlag;
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法:两个数组取中位数 的相关文章

  • ChatGPT的接口在哪

    ChatGPT本身不是一个独立的接口 而是一个预训练的自然语言处理模型 如果您需要使用ChatGPT来实现某个自然语言处理任务 例如文本生成 问答等 您可以使用Python中的深度学习框架 如TensorFlow PyTorch 加载预训练
  • 谈我对于ajax的理解

    Ajax的全称是Asynchronous JavaScript and XML 中文名称定义为异步的JavaScript和XML Ajax是Web2 0技术的核心由多种技术集合而成 使用Ajax技术不必刷新整个页面 只需对页面的局部进行更新
  • qt 信号槽默认参数 toggled 和 trigger的区别

    toggled和trigger区别 1 toggle 类似开关 具有2个状态 打开 关闭 使用这个信号 是在这2个状态之间切换 2 trigger是一次性的 点击后 无法改变状态 要么是打开 要么是关闭 参考 http blog csdn
  • c# 对txt文件的读取与写入

    C txt文件分析 读取与写入 c 中对txt文件的读取写入在工作中用到的很多 今天写一个之前工作中用到的小demo 案例场景要求 txt文件中为很多条标记时间戳的报文 需要计算出每条报文从开始接收到结束用了多长时间 案例执行 如txt文件
  • Java数据结构和算法(一)——简介

    本系列博客我们将学习数据结构和算法 为什么要学习数据结构和算法 这里我举个简单的例子 编程好比是一辆汽车 而数据结构和算法是汽车内部的变速箱 一个开车的人不懂变速箱的原理也是能开车的 同理一个不懂数据结构和算法的人也能编程 但是如果一个开车
  • apk文件 -- 反编译

    源博客 https www cnblogs com mfrbuaa p 4588057 html 编译工具 apktool 资源文件获取 能够提取出图片文件和布局文件进行使用查看 dex2jar 将apk反编译成java源代码 classe
  • Python中多线程和线程池的使用方法

    Python是一种高级编程语言 它在众多编程语言中 拥有极高的人气和使用率 Python中的多线程和线程池是其强大的功能之一 可以让我们更加高效地利用CPU资源 提高程序的运行速度 本篇博客将介绍Python中多线程和线程池的使用方法 并提
  • ad9361收发异常问题分析

    最近在调试ad9361 发送都调试好了 但是接收一直没调试好 折腾了一个多月才搞定接收 根据官方提供的api代码 需要修改的有 1 修改reference clk rate参考时钟 2 修改xo disable use ext refclk
  • CTF——被改错的密码

    http ctf idf cn index php g game m article a index id 29 cca9cc444e64c8116a30la00559c042b4看着像一串MD5加密 但是实际不是 去掉中间的l 进行md5
  • 新手小白一看就懂的Excel技能之入门基础

    很多同学开开心心拿到新买的电脑 开机一看 桌面干干净净的 想打开Excel 半天找不到 这些痛 只有新手小白才能懂 今天 我给大家好好讲讲怎么使用Excel 鼠标左键点击电脑桌面左下角的 搜索 输入 Excel 看到 Microsoft O
  • 过拟合现象,原因,以及降低过拟合的方法

    一 什么是过拟合 为什么要避免过拟合 图1 1 Overfit Normal 上图是一张使用线性回归拟合二维样本数据的matlab输出图片 其中Normal曲线是使用使用了带参数空间限制的最小二乘法进行求解的模型 Overfit曲线是使用最
  • 微服务中常用的注解

    注解的定义 Annotation 注解 用于为Java代码提供元数据 简单理解注解可以看做是一个个标签 用来标记代码 是一种应用于类 方法 参数 变量 构造器及包的一种特殊修饰符 1 Target 表示该注解类型所使用的程序元素类型 结合E
  • 机器学习实践(一)—sklearn之概述

    1956年 人工智能元年 人类能够创造出人类还未知的东西 这未知的东西人类能够保证它不误入歧途吗 一 机器学习和人工智能 深度学习的关系 机器学习是人工智能的一个实现途径 深度学习是机器学习的一个方法发展而来 二 机器学习 深度学习的应用场
  • Office 2019 for Mac 安装

    1 下载微软官方Office 2019 for Mac 64位 大小 1 7G 2 按照提示安装Office 2019 for Mac 3 下载14743217 Microsoft Office 2019 VL Serializer安装器
  • 发qq邮件被对方服务器拒绝,QQ被对方拉黑了。我发QQ邮件对对方能收到吗?

    QQ被对方拉黑了 我发QQ邮件对对方能收到吗 以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 让我们赶快一起来看一下吧 QQ被对方拉黑了 我发QQ邮件对对方能收到吗 拉黑删除能收到的 邮件
  • Scrapy实战案例--抓取股票数据并存入SQL数据库(JS逆向)

    目标网址 http webapi cninfo com cn marketDataZhishu 之前在这篇文章里面对该网站的JS进行了一个逆向的解析 JS逆向解析案例 接下来我们来创建一个Scrapy项目来爬取某潮的数据并保存在数据库中 过
  • 基于LayUI+Servlet的权限管理系统的设计

    权限管理是所有后台系统的都会涉及的一个重要组成部分 主要目的是对不同的人访问资源进行权限的控制 避免因权限控制缺失或操作不当引发的风险问题 如操作错误 隐私数据泄露等问题 本系统基于JSP Servlet JDBC LayUI的技术 在系统
  • WebRTC打开本地摄像头

    本文使用WebRTC的功能 打开电脑上的摄像头 并且把摄像头预览到的图像显示出来 纯网页实现 能支持除IE外的多数浏览器 手机浏览器也可用 本文链接 引入依赖 我们需要引入adapter latest js 这个WebRTC adapter
  • 计算机中模板与母版的区别,ppt中母版模板主题版式之间的区别和联系?

    ppt中母版模板主题版式之间的区别和联系 由会员分享 可在线阅读 更多相关 ppt中母版模板主题版式之间的区别和联系 1页珍藏版 请在人人文库网上搜索 1 模板是现成的样式 包括图片动画等 直接输入内容就可以使用了 母版是自己设计模板的菜单
  • STM32单片机Flash模拟EEPROM

    摘要 STM32单片机都带有ROM和RAM 其中STM32根据自身的ROM Flash 可以分为小容量产品 中容量产品 大容量产品 根据FLASH容量可以分为 小容量 0 32K 中容量 64 128K 大容量 256K以上 包含256K

随机推荐

  • 【Green公式】Hunter’s Apprentice(判断多边形为顺时针或逆时针)--鞋带公式

    题目描述 When you were five years old you watched in horror as a spiked devil murdered your parents You would have died too
  • C语言字节对齐

    文章来源于 点击打开链接 文章最后本人做了一幅图 一看就明白了 这个问题网上讲的不少 但是都没有把问题说透 一 概念 对齐跟数据在内存中的位置有关 如果一个变量的内存地址正好位于它长度的整数倍 他就被称做自然对齐 比如在32位cpu下 假设
  • ElasticSearch基础操作入门

    参考 4条消息 教你快速入门ElasticSearch 超详细简单 暗余的博客 CSDN博客 elasticsearch菜鸟教程 一个索引就是一个拥有几分相似特征的文档的集合 使用Chrome浏览器ElasticSearch Head 具体
  • 巨潮资讯网年报爬虫

    巨潮资讯网年报爬虫 代码直接复制即可使用 这是一个Post请求爬虫 与Get请求存在一点小区别 不过核心思想是一致的 Tips 需要在py文件夹目录下 新建一个 年报 名称的文件夹 存放下载的报表 同时在py文件夹目录下 需要一个stock
  • 游戏开发Unity杂项知识系列: CSharpCodeProvider could not be found in the namespace Micrrosoft.CSharp

    unity 进行build and run 时报错 The type name CSharpCodeProvider could not be found in the namespace Microsoft CSharp This typ
  • numpy学习笔记

    Numpy基础数据结构 NumPy数组是一个多维数组对象 称为ndarray 其由两部分组成 实际的数据 描述这些数据的元数据 import numpy as np import time ar np array 1 2 3 4 5 6 7
  • 什么是拷贝构造函数?拷贝构造函数何时被调用

    1 什么是拷贝构造函数 CA const CA C 就是我们自定义的拷贝构造函数 可见 拷贝构造函数是一种特殊的构造函数 函数的名称必须和类名称一致 它的唯一的一个参数是本类型的一个引用变量 该参数是const类型 不可变的 例如 类X的拷
  • python widget_python 图形界面

    Python自带的库是支持Tk的Tkinter 使用Tkinter 无需安装任何包 就可以直接使用 Tk是一个图形库 支持多个操作系统 导入Tkinter包的所有内容 from tkinter import 从Frame派生一个Applic
  • R与R Studio及R tools不冲突版本

    R与R Studio及R tools不冲突版本 R 3 6 3 R Studio 1 1 463 R tools 35 R 4 0 2 R Studio 1 3 1073 R tools 4 0 其他造成R Studio打开空白问题 1 路
  • Python+Requests+Unittest+Excel 接口自动化测试框架之Request模块01

    1 Requests模块 a Request模块是Python中可以实现模拟Http协议的模块 b 安装方式很多 可以用pip install requests 2 举例 import requests class Http Request
  • php://filter伪协议(总结)

    前言 这篇文章主要是关于php filter伪协议中的知识点总结 分析了常见的用法 文章目录 前言 php filter伪协议总结 php filter伪协议介绍 php filter伪协议使用方法 php filter过滤器分类 filt
  • CSDN-markdown编辑器

    这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题 有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中 居左 居右 Sma
  • 大数据分析机器学习的数据清理和准备

    数据清理和准备是任何机器学习项目中至关重要的第一步 尽管我们经常认为数据科学家花费大量时间来修改算法和机器学习模型 但现实情况是大多数数据科学家花费大量时间来清理数据 在大数据分析机器学习的数据清理和准备中 我们将逐步介绍使用Python进
  • 管理神话之23:随便多少人你都能管

    原文作者 Johanna Rothman Cindy 我要给你的团队再加三个人 Patrick 公司的CTO 斜靠在门口 话音刚落 他转身就想离开 等等 这事我们要讨论一下 你不能这样扔下炸弹后就一走了之 你为什么要我再招更多的人 Cind
  • java并发篇面试

    文章目录 java并发篇 java如何开启线程 怎么保证线程安全 Volatile和Synchronized有什么区别 Volatile能不能保证线程安全 DCL Double check Lock 单例为什么要加Volatile JAVA
  • pycharm激活, pycharm远程调试

    pycharm professional 2017 2 3下载 百度盘公开地址 https pan baidu com s 1geDnVVX 1 pycharm激活 license server 1 激活窗口选择 Activate new
  • C++ Thread

    Thread 线程库 线程的创建 detach 句柄独立 线程资源转移 sleep for 全局函数线程化 joinable hardware concurrency 线程的互斥 原子操作定义 互斥锁 try lock recursive
  • Spring bean的生命周期

    对于普通的Java对象 当new的时候创建对象 当它没有任何引用的时候被垃圾回收机制回收 而由Spring IoC容器托管的对象 它们的生命周期完全由容器控制 bean的声明 bean的声明有好几种 如上图 上图声明的一些bean信息可以通
  • Hello Vulkan(五)

    上一期技术分享中 我们讲述了如何关于Vulkan的Data Buffers使用及VMA内存管理器使用 自己创建或使用VMA在显存里创建Buffers 并在CPU进行读取或写入 本期将继续分享关于Vulkan的技术 内容是非常有趣的部分 即
  • 算法:两个数组取中位数

    要求 任意两个数组取中位数 在保证空间复杂度的同时 时间复杂度要求log m n package com flash hance import java util ArrayList import java util List author