Java数据结构第十七章、手撕位图

news2025/1/11 11:06:11

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】

1. 遍历,时间复杂度O(N)
2. 排序(O(NlogN)),利用二分查找: logN
3. 位图解决
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:

一、位图

1.1位图的概念

所谓位图,就是用每一位来存放某种状态,适用于海量数据,整数,数据无重复的场景。通常是用来判断某个数据存不存在的。

如上例子,10个整数本应该存放需要40个字节,此时用位图只需要3个字节。

小技巧:10亿个字节大概是0.9G,可看做是1G,10亿个比特位大概是119兆,看做128兆

1.2模拟实现位图

package bitsetdemo;

import java.util.Arrays;

/**
 * @Author 12629
 * @Description:
 */
public class MyBitSet {

    public byte[] elem;
    //记录当前位图当中 存在了多少个有效的数据
    public int usedSize;

    public MyBitSet() {
        this.elem = new byte[1];
    }

    /**
     *
     * @param n 多少位
     *          n = 12
     * 有可能会多给一个字节,但是无所谓。
     */
    public MyBitSet(int n) {
        this.elem = new byte[n/8+1];
    }

    /**
     * 设置某一位为 1
     * @param val
     */
    public void set(int val) {
        if(val < 0) {
            throw new IndexOutOfBoundsException();
        }
        int arrayIndex = val / 8 ;
        //扩容
        if(arrayIndex > elem.length-1) {
            elem = Arrays.copyOf(elem,arrayIndex+1);
        }
        int bitIndex = val % 8;

        elem[arrayIndex] |=  (1 << bitIndex); //不能进行异或

        usedSize++;
    }

    /**
     * 判断当前位  是不是1
     * @param val
     */
    public boolean get(int val) {
        if(val < 0) {
            throw new IndexOutOfBoundsException();
        }
        int arrayIndex = val / 8 ;
        int bitIndex = val % 8;

        if((elem[arrayIndex] & (1 << bitIndex)) != 0) {
            return true;
        }
        return false;
    }

    /**
     * 将对应位置 置为 0
     * @param val
     */
    public void reSet(int val) {
        if(val < 0) {
            throw new IndexOutOfBoundsException();
        }
        int arrayIndex = val / 8 ;
        int bitIndex = val % 8;
        elem[arrayIndex] &= ~(1 << bitIndex);
        usedSize--;
    }

    //当前位图中记录的元素的个数
    public int getUsedSize() {
        return usedSize;
    }

}

1.3位图测试+位图排序法

package bitsetdemo;

import java.util.BitSet;
public class Test {

    public static void main3(String[] args) {
        int[] array = {1,3,2,13,10,3,14,18,3};
        MyBitSet myBitSet = new MyBitSet(18);
        for (int i = 0; i < array.length; i++) {
            myBitSet.set(array[i]);
        }
        //位图排序法

        for (int i = 0; i < myBitSet.elem.length; i++) {
            for (int j = 0; j < 8; j++) {
                if((myBitSet.elem[i] & (1 << j) ) != 0 ) {
                    System.out.println(i*8+j);
                }
            }
        }
    }

    public static void main2(String[] args) {
        int[] array = {1,2,3,10,4,18,130};
        MyBitSet myBitSet = new MyBitSet(18);
        for (int i = 0; i < array.length; i++) {
            myBitSet.set(array[i]);
        }
        System.out.println(myBitSet.getUsedSize());
        System.out.println(myBitSet.get(10));
        myBitSet.reSet(10);
        System.out.println(myBitSet.get(10));
    }

    public static void main1(String[] args) {
        int[] array = {1,2,3,10,4,18,13};
        BitSet bitSet = new BitSet(18);
        for (int i = 0; i < array.length; i++) {
            bitSet.set(array[i]);
        }
        System.out.println(bitSet.get(100));
    }
}

1.4位图的应用

1. 快速查找某个数据是否在一个集合中

2. 排序 + 去重

3. 求两个集合的交集、并集等

4. 操作系统中磁盘块标记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1082436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重置Mac电脑的SMC怎么操作,重置SMC方法分享~

SMC 负责管理 Mac 上的电源。重置 SMC 可以解决一些与电源或散热管理相关的不常见问题。今天重置SMC教程给大家分享一下&#xff0c;需要的小伙伴看过来&#xff01; 如何判断您是不是需要重置 SMC 若出现以下症状&#xff0c;则表明可能需要重置 SMC&#xff1a; 电池无法充电…

Exim 中的漏洞!

我们将继续分享有关流行网络安全漏洞的最新信息。 Exim 中的 CVE-2023-42115漏洞&#xff01; CVE-2023-42115是开源 Exim 4 SMTP 邮件服务器项目中的一个远程代码执行漏洞。问题的严重性不容小觑。据我们的分析师称&#xff0c;目前网络中存在漏洞的 Exim 服务器超过 350 万台…

18基于matlab的二阶动态系统的滑膜控制,程序已调通,可直接运行。标价为程序价格,不包含售后。程序保证可直接运行。

基于matlab的二阶动态系统的滑膜控制&#xff0c;程序已调通&#xff0c;可直接运行。标价为程序价格&#xff0c;不包含售后。程序保证可直接运行。 18matlab滑膜控制 (xiaohongshu.com)

【C++入门】命名空间详解(从零开始,冲击蓝桥杯)

C入门 命名空间 南喵小鸡汤程序员可以让步&#xff0c;却不可以退缩&#xff0c;可以羞涩&#xff0c;却不可以软弱&#xff0c;总之&#xff0c;程序员必须是勇敢的。一 . 命名空间的介绍二.命名空间的实际应用1.为什么要有命名空间我们在使用变量时,通常会为他定义一个名字,在…

graphviz 绘制森林

代码 digraph Forest {node [fontname"Arial", shapecircle, stylefilled, color"#ffffff", fillcolor"#0077be", fontsize12, width0.5, height0.5];edge [fontname"Arial", fontsize10, color"#333333", arrowsize0.5];/…

Node基础概念,先了解一下

Nodejs是基于Chrome V8引擎的服务器端JavaScript运行环境&#xff0c;也就是说可以在浏览器之外的主机上运行JavaScript。 NodeJS Nodejs有三部分组成&#xff1a;标准库、中间层和底层库。 标准库&#xff1a;是给开发人员直接调用的API&#xff0c;比如HTTP模块&#xff1b…

Vulnhub Me-and-My-Girlfriend

一、信息收集 1.nmap 端口扫描 发现开发了22、80 2.访问ip&#xff0c;右击查看源代码 发现需要利用X-Forwarded-For 插件&#xff1a;X-Forwarded-For Header 挂上代理后&#xff1a; 出现以下页面&#xff1a; 先注册一个账户&#xff0c;然后再登录 发现有参数进行传…

C语言系统化精讲(二):C语言数组详解

文章目录 一、数组的基本概念二、一维数组2.1 一维数组的定义2.2 一维数组初始化2.3 一维数组的引用 三、二维数组3.1 二维数组的定义3.2 二维数组初始化3.3 二维数组的引用 四、C语言数组是静态的&#xff0c;不能插入或删除元素五、C语言数组的越界和溢出5.1 数组越界5.2 数组…

第一个2DGodot游戏-从零开始-逐步解析

视频教程地址&#xff1a;https://www.bilibili.com/video/BV1Hw411v78Y/ 前言 大家好&#xff0c;这一集我将要带领大家完成官方文档里的第一个2DGodot游戏&#xff0c;从零开始&#xff0c;逐步解析&#xff0c;演示游戏的制作全过程&#xff0c;尽量让&#xff0c;就算是新…

C++ - 包装器 - bind()函数

包装器 在 C 当中可能会有各种各样的可调用类型&#xff0c;比如 函数指针&#xff0c;仿函数&#xff0c;lambda 等等&#xff0c;那么这么多的可调用类型&#xff0c;我们在使用的时候就会犯迷糊&#xff0c;那可不可以统一控制一下呢&#xff1f; function包装器&#xff…

关于SSA算法中矩阵的3种运算:转置、求逆、相乘

1、矩阵转置 // 矩阵转置(二维矩阵)public static double[][] transposeTwo(double[][] matrix) {int rows matrix.length;int cols matrix[0].length;double[][] transposedMatrix new double[cols][rows];for (int i 0; i < rows; i) {for (int j 0; j < cols; j)…

一篇博客带你学会关于Vuex使用

前言&#xff1a; 在我们之前我们的学习vue知识中&#xff0c;我们组件传递方式有父传子&#xff0c;子传父&#xff0c;这两种方法传递参数复杂&#xff0c;所以我们今天来学习Vuex&#xff0c;就可以解决这个传递的问题&#xff01;&#xff01;&#xff01; 一&#xff0c;V…

【算法思考】端到端实例分割模型 SOLO

目录 背景工作总结 背景 不同于语义分割&#xff0c;实例分割不仅需要输出图像的语义蒙版&#xff0c;还要对图像中不同的实例作区分。如下图所示&#xff0c;实例分割任务需要多不同的羊做区分&#xff0c;输出不同的实例蒙版。 由于图片中实例个数的不确定性&#xff0c;实例…

第二章 C++的输出

系列文章目录 第一章 C的输入 文章目录 系列文章目录前言一、个人名片二、cout三、printf总结 前言 今天来学C的输出吧&#xff01; 一、个人名片 二、cout cout 三、printf printf 总结 最近懒得写博客怎么办&#xff1f;

【技术研究】环境可控型原子力显微镜超高真空度精密控制解决方案

摘要&#xff1a;针对原子力显微镜对真空度和气氛环境精密控制要求&#xff0c;本文提出了精密控制解决方案。解决方案基于闭环动态平衡法&#xff0c;在低真空控制时采用恒定进气流量并调节排气流量的方法&#xff0c;在高真空和超高真空控制时则采用恒定排气流量并调节进气流…

Docker系列--网络的配置

原文网址&#xff1a;Docker系列--网络的配置_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Docker的网络的配置。 官网网址 https://docs.docker.com/engine/reference/commandline/network/ 网络的默认设置 Docker启动之后&#xff0c;系统中会产生一个名为docker0的…

2015架构真题(五十)

供应链中信息流覆盖了供应商、制造商和分销商&#xff0c;信息流分为需求信息流和供应信息流&#xff0c;&#xff08;&#xff09;属于需求信息流&#xff0c;&#xff08;&#xff09;属于供应信息流。 库存记录生产计划商品入库单提货发运单 客户订单采购合同完工报告单销售…

Leetcode.2867 统计树中的合法路径数目

题目链接 Leetcode.2867 统计树中的合法路径数目 rating : 2428 题目描述 给你一棵 n n n 个节点的无向树&#xff0c;节点编号为 1 1 1 到 n n n 。给你一个整数 n n n 和一个长度为 n − 1 n - 1 n−1 的二维整数数组 e d g e s edges edges &#xff0c;其中 e d g …

Matlab地理信息绘图—风玫瑰图

文章目录 风玫瑰图的作用Matlab代码实现结果展示 风玫瑰图的作用 风玫瑰图&#xff08;Wind Rose Plot&#xff09;是一种用于可视化风向和风速分布的图表。它通常以极坐标形式呈现&#xff0c;其中角度表示风向&#xff0c;半径表示风速的频率或相对概率。风玫瑰图对于理解和呈…

项目log日志mysql记录,熟悉python的orm框架

直接在项目里面创建一个class&#xff0c;这个类对应着mysql里面的表 我们运行项目&#xff0c;可以自动建立表 在.env中找到mysql的配置信息&#xff0c;这个是在NB服务器上运行的mysql&#xff0c;localhost需要变成NB服务器的ipv4地址 使用Mysql工具连接查看&#xff0c;连…