Go最新离散化及模板详解_离散化模版(1),Golang面试题2024高级

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

10^3

103个数而开一个

1

0

6

10^6

106的数组过于浪费空间,因此我们可以采用离散化的方法,将这些数映射到

0

1

0

3

0-10^3

0−103上,这个过程就叫做离散化。

注意:这里的映射数字指的是元素的下标数字,而非元素本身的数值。

算法思路

对于有序数组进行映射,其基本思路如下:

image-20221013133143457

针对可能存在的两个问题,有以下的解决方法:

1.数组中可能存在重复元素 ==> 对数组进行去重

常见写法:用cpp中的库函数来实现。

unique函数:将数组中的元素去重,并且返回去重后数组的尾端点。

image-20221013133734502

vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

2.如何算出x离散化后的值 ==> 用二分法

int find(int x) // 找到第一个大于等于x的位置
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    // 映射到1, 2, ...n
    // 不加1的话是从0开始映射。
    return r + 1;
}

模板
vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    // 映射到1, 2, ...n
    // 不加1的话是从0开始映射。
    return r + 1;
}

例题:区间和

假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。

现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加c。

接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r]之间的所有数的和。

输入格式

第一行包含两个整数 n 和 m。

接下来 n 行,每行包含两个整数 x 和 c。

再接下来 m 行,每行包含两个整数 l 和 r。

输出格式

共 m 行,每行输出一个询问中所求的区间内数字和。

数据范围

1

0

9

x

1

0

9

−109≤x≤109

−109≤x≤109,

1

n

,

m

1

0

5

1≤n,m≤10^5

1≤n,m≤105,

1

0

9

l

r

1

0

9

−109≤l≤r≤109

−109≤l≤r≤109,

10000

c

10000

−10000≤c≤10000

−10000≤c≤10000

输入样例

3 3
1 2
3 6
7 5
1 3
4 6
7 8

输出样例

8
0
5

题目分析

数据范围很大,因此不能用哈希表,并且数轴上的数字是离散的,整体是稀疏的,我们可以采用离散化的方式进行映射。

  • add : 保存真实的下标和相应的值
  • alls : 用来保存真实的下标和映射的下标的关系
  • query : 用来保存查询的左右两个端点
  • a : 保存映射的坐标所对应的值
  • s: 保存映射的坐标所对应的值的前缀和

第一步: 输入数轴上所对应的值

for(int i=0;i<n;i++)
{
	int index,x; cin>>index>>x;
	add.push\_back({index,x});//index 是我们真实的下标 x是数值
	alls.push\_back(index);// 将真实的下标和我们想象的坐标建立映射关系
}

第二步: 输入我们的查询的区间

for(int i=0;i<m;i++)
	{
		int l,r; cin>>l>>r;
		query.push\_back({l,r});//保存查询的区间
		
		alls.push\_back(l);
		//将其左右端点也映射进来,目的是可以让我们在虚拟的映射表里找到,这对于我们后面的前缀和操作时是十分的方便的。
		//如果当我们在虚拟的映射表里找的时候,如果没有找到左右端点,那么前缀和无法求。
		alls.push\_back(r);
	}

第三步: 将虚拟的坐标排序并去重

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

如果当我们在虚拟的映射表里找的时候,如果没有找到左右端点,那么前缀和无法求。
alls.push_back®;
}


**第三步: 将虚拟的坐标排序并去重**



[外链图片转存中...(img-oqd5ePeY-1715898859632)]
[外链图片转存中...(img-HphpMj5c-1715898859633)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值