离散化以及树状数组

news2025/1/12 6:10:29

今天我们先来讲一讲什么叫做离散化(简单的映射关系)

一、离散化

一、概念:就是把一个无限的空间去映射到一个有限的空间中去(通俗的可以理解成将数据相应的缩小)为了更好的理解,请看下图:

       已知A和B两条直线,你觉得两条直线是否长度相等? 我们无论是肉眼看还是拿比较紧密的尺子进行测量,A和B的长度永远不可能相等,但是在某一方面,它们的长度是相等的,看下图:

      以直线A和直线B做一个三角形,假设有两条直线相交与A和B,在A和B中分别相交与点m n和点m' n',由此可知,我们都可以在直线B上找到与A中的点一一对应的点, 所以我们可以理解成A线段中点作成集合和B线段中点作成集合相等,所以我们理解成A和B的长度相等,所以这就是映射,想必大家已经对映射有了最基本的概念,下面我们来讲解什么是离散化。

二、适用范围:数组中数量不是很多,但是数值很大

例:[-1,2,50,1000]-->[0,1,2,3]  这个映射过程就是离散化

注意:一般有负数或者是数值较大,我们会采用离散化

  • 负数:因为数组中的索引时非负数,所以我们不能直接将对应的值映射到数组中的索引中,所以我们需要使用离散化。
  • 如果数值非常大,加入有一个值为100000,我们总不能创建一个长度为100000长度的数组,所以我们需要进行离散化

离散化的步骤:

  1. 用一个辅助数组将你需要离散化的数据保存起来(对原数组进行复制)
 //原数组 
 int[] nums={-9,5,-6,5,10000};
//辅助数组
 int[] aim= Arrays.copyOfRange(nums,0,nums.length);

      2.对辅助数组进行排序、去重

//对原数组进行去重、排序,并生成一个新的数组c 
int [] c=Arrays.stream(aim).distinct().sorted().toArray();

大体步骤: 

 二分查找的方法给大家分享代码:

    // 二分查找法
    private int find(int[] arr, int num) {
        if(arr == null || arr.length == 0){ //数组为空
            return -1;
        }
        int left=0;
        int right=arr.length-1;
        // 先找中间值
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (arr[mid] == num) {
                return mid;
            } else if (arr[mid] > num) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }

 二、树状数组

                       树状数组                                                                           二叉树

树状数组优缺点:

优点:修改和查询操作复杂度于线段树一样都是logN,但是常数比线段树小,并且实现比线段树简单。

缺点:扩展性弱,线段树能解决的问题,树状数组不一定能解决.

注意:假设我们修改了5这个结点上的值,在树状数组中我们只需要修改结点6、8上的值,那我们怎么才能决定我们修改了一个结点后修改哪些结点呢?下来我们来共同看看

 lowbit(x)运算:

 //二进制
    public int lowbit(int x){
        return x&(-x);
    }

 在这里我们先复习一个数的原码、反码、补码怎么进行计算

原码:二进制    正数的最高位为0    负数的最高位为1    最高位为符号位

反码:正数的反码与原码相同     负数的反码除符号位不变,其他位置取反   0-1    1-0

补码:正数的补码与原码相同     负数的补码相当于负数的反码+1

假设我们修改的那个节点为5

5+1=6   

6+2=8 

所以不断的对i值进行lowbit操作,便可以获得下一个+值

   //树状数组进行添加元素
    public void add(int index,int val){
        for (int i = index; i <this.C.length; i+=lowbit(i)) {
             this.C[i]+=val;
        }
    }

 正推如此,倒推也是如此(比如求和,大的区间是由很多小的区间合并而来)

    //元素查询
    public int preSarch(int index){
        int sum=0;
        for (int i =index; i >0; i-=lowbit(i)) {
            sum+=this.C[i];
        }
        return sum;
    }

 如果要进行修改操作:

 public void update(int index, int val) {
        //添加的val是差值量
       this.add(index+1,val-this.A[index]);
       //更改原数组中的值
       this.A[index]=val;
    }

 树状数组源代码(模板):

    //数组
    private int[] A;
    //树状数组
    private int[] C;
    //长度
    private int length;
     //二进制
    public int lowbit(int x){
        return x&(-x);
    }

    public NumArray(int[] nums) {
         this.A= Arrays.copyOfRange(nums,0,nums.length);
         this.C=new int[nums.length+1];
         this.length=nums.length;
         //构造树状数组,将原数组中的数添加到树状数组中
        for (int i = 0; i <this.length; i++) {
            this.add(i+1,this.A[i]);
        }
    }
    //树状数组进行添加元素
    public void add(int index,int val){
        for (int i = index; i <this.C.length; i+=lowbit(i)) {
             this.C[i]+=val;
        }
    }
    //元素查询
    public int preSarch(int index){
        int sum=0;
        for (int i =index; i >0; i-=lowbit(i)) {
            sum+=this.C[i];
        }
        return sum;
    }


    public void update(int index, int val) {
        //添加的val是差值量
       this.add(index+1,val-this.A[index]);
       //更改原数组中的值
       this.A[index]=val;
    }

    public int sumRange(int left, int right) {
     return preSarch(right+1)-preSarch(left);
    }

       想必大家已经对离散化、数状数组有了大概的认识,相信这些知识能帮助你在算法的学习过程中走的更远!!!

 

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

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

相关文章

90后测试员:“入职阿里,这一次,我决定不跳槽了...”

所谓“舒适”生活 记得上一份工作是去年听从了朋友的意见&#xff0c;“你一定要找一份舒适的工作&#xff0c;这样你一天就有好多时间玩&#xff0c;好多时间干自己想干的事情&#xff0c;摸鱼真香&#xff01;” 在这份“教导”下&#xff0c;开始了我的找工作之旅&#xf…

Day972.OAuth 2.0是要通过什么方式解决什么问题? -OAuth 2.0

OAuth 2.0是要通过什么方式&#xff1f;解决什么问题&#xff1f; 使用某个App 的时候&#xff0c;是直接使用了第三方帐号&#xff08;比如微信、微博&#xff09;登录&#xff0c;还是选择了重新注册新用户&#xff1f;如果选择了重新注册用户&#xff0c;那你还得上传头像、…

DPDK imissed、ierrors、rx_nombuf

在采用DPDK进行网络抓包时常常会通过rte_eth_stats_get函数获取当前网卡的丢包状态&#xff0c;首先看一下该函数的声明&#xff1a; // 函数声明(dpdk-stable-19.11.3/lib/librte_ethdev/rte_ethdev.h) int rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats…

高级程序员和新手小白程序员区别你是那个等级看解决bug速度

IT入门深似海 ,程序员行业&#xff0c;我觉得是最难做的。加不完的班&#xff0c;熬不完的夜。 和产品经理&#xff0c;扯不清,理还乱的宿命关系 一直都在 新需求-做项目-解决问题-解决bug-新需求 好像一直都是这么一个循环。&#xff08;哈哈哈&#xff09;我觉得一个好的程序…

【传染病模型】

传染病模型&#xff1a;原理介绍与应用实战 一、概述 在公共卫生研究中&#xff0c;传染病模型是一种关键的理论工具&#xff0c;用于理解和预测传染病的传播方式。 二、传染病模型原理 2.1 SIR模型 SIR模型是描述感染性传播病病人数量变化最简单的模型之一。其中&#xf…

不要再重复造轮子了,这几款开源工具类库贼好使

在实际项目开发中&#xff0c;从稳定性和效率的角度考虑&#xff0c;重复造轮子是不被提倡的。但是&#xff0c;自己在学习过程中造轮子绝对是对自己百利而无一害的&#xff0c;造轮子是一种特别能够提高自己系统编程能力的手段。 基于 SpringBoot Vue uni-app 实现的全套电商…

小白如何快速入门?

入门 Web 安全、安卓安全、二进制安全、工控安全还是智能硬件安全等等&#xff0c;每个不同的领域要掌握的技能也不同。当然入门 Web 安全相对难度较低&#xff0c;也是很多人的首选。主要还是看自己的兴趣方向吧。 本文就以下几个问题来说明网络安全大致学习过程&#x1f447…

【CSS3系列】第三章 · CSS3新增边框和文本属性

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

5月总共面试15次,我真哭了....

3年测试经验原来什么都不是&#xff0c;只是给你的简历上画了一笔&#xff0c;一直觉得经验多&#xff0c;无论在哪都能找到满意的工作&#xff0c;但是现实却是给我打了一个大巴掌&#xff01;事后也不会给糖的那种... 先说一下自己的个人情况&#xff0c;普通二本计算机专业…

【Spring Cloud】Spring Cloud 中 Zuul 网关原理及其配置

文章目录 前言一、Zuul 网关简介二、Zuul 网关使用场景三、Zuul 网关原理3.1 过滤器3.2 生成路由并发送给后端服务3.3 处理路由响应 四、Zuul 网关配置过程步骤1&#xff1a;添加依赖步骤2&#xff1a;创建配置类步骤3&#xff1a;配置路由规则步骤4&#xff1a;添加过滤器 五、…

【C# 10 和 .NET 6】使用MVC模式构建网站(笔记2)

3. 自定义 ASP.NET Core MVC 网站 现在您已经了解了基本 MVC 网站的结构&#xff0c;您将对其进行自定义和扩展。您已经为 Northwind 数据库注册了一个 EF Core 模型&#xff0c;因此下一个任务是在主页上输出一些数据。 3.1 定义自定义样式 主页将显示 Northwind 数据库中77 种…

常见的IO模型

计算机硬件包括CPU&#xff0c;内存&#xff0c;网卡 为了避免用户应用和操作系统内核产生冲突乃至内核崩溃&#xff0c;用户应用和内核是隔离开的 1)进程的寻址空间会被划分成两部分&#xff0c;内核空间和用户空间&#xff0c;内核和用户应用都无法直接访问物理内存&#xff…

【Vue】Vuex,Vue-Router

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 Vuexvue-router Vuex 将公用的数据统一存放在store(全局数据中心)中&#xff0c;实现更方便的跨…

从实习到秋招成为一名安全工程师,我经历了什么

前言 借朋友口述总结了安全招聘面试经历分享&#xff0c;希望更多的人看到这篇文&#xff0c;从中得到启发&#xff0c;找到自己心仪的工作。 基本情况 签了字节的三方&#xff0c;秋招终于告一段落。从八月份边实习边准备秋招到现在&#xff0c;经历了许多&#xff0c;这篇帖…

2023金三银四Java开发岗热门面试题总结

最近很多粉丝朋友私信我说&#xff1a;熬过了去年的寒冬却没熬过现在的内卷&#xff1b;打开 Boss 直拒一排已读不回&#xff0c;回的基本都是外包&#xff0c;薪资还给的不高&#xff0c;对技术水平要求也远超从前&#xff1b;感觉 Java 一个初中级岗位有上千人同时竞争&#…

都说00后已经躺平了,但是有一说一,该卷的还是卷啊。

这不&#xff0c;三月份春招我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天&#xff0c;原来这位小老弟家里条件不太好&…

Java学习路线(21)——网络通信

一、网络通信三件套 1、IP地址&#xff1a; 设备在网络中的地址&#xff0c;唯一标识 概念&#xff1a; Internet Protocal&#xff0c;简称为IP&#xff0c;全称“互联网协议地址”。 常见分类&#xff1a; IPv4&#xff08;32位&#xff09; 和 IPv6&#xff08;128位&#…

IDEA debug断点调试认识与技巧

IDEA debug断点调试认识与技巧 文章目录 IDEA debug断点调试认识与技巧认识debug常见的操作如何开启debug模式 基本用法和快捷键1、显示执行点&#xff08;Alt F10&#xff09;2、步过&#xff08;F8&#xff09;3、步入&#xff08;F7&#xff09;4、强制步入&#xff08;Alt…

【容器云架构】确定容器网络calico最佳网络选项

大图 了解 Calico 支持的不同网络选项&#xff0c;以便您可以根据需要选择最佳选项。 价值 Calico 灵活的模块化架构支持广泛的部署选项&#xff0c;因此您可以选择适合您特定环境和需求的最佳网络方法。这包括使用各种 CNI 和 IPAM 插件以及底层网络类型以非覆盖或覆盖模式运行…

线性回归模型一二三

文章目录 什么是线性回归线性回归的求解一元线性回归&#xff08;最小二乘法&#xff09;多元线性回归 衍生求解梯度下降智能搜索算法求解&#xff08;PSO&#xff09;简要分析 线性回归与简单神经网络联系类比推导反向传播 总结 什么是线性回归 线性回归的基本假设是&#xf…