既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
0
6
10^6
106的数组过于浪费空间,因此我们可以采用离散化的方法,将这些数映射到
0
−
1
0
3
0-10^3
0−103上,这个过程就叫做离散化。
注意:这里的映射数字指的是元素的下标数字,而非元素本身的数值。
算法思路
对于有序数组进行映射,其基本思路如下:
针对可能存在的两个问题,有以下的解决方法:
1.数组中可能存在重复元素 ==> 对数组进行去重
常见写法:用cpp中的库函数来实现。
unique函数:将数组中的元素去重,并且返回去重后数组的尾端点。
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);
}
第三步: 将虚拟的坐标排序并去重
为啥去重:
是因为当我们输入
3 5
3 6
即给数轴上3的点加5 再加 6时。此时我们的坐标映射表里有了两个3 3 但其实它们对应的是同一个坐标。故需要去重,排序。
sort(alls.begin(), alls.end());//排序
![img](https://img-blog.csdnimg.cn/img_convert/1c48fb4d8b796ca5a2390f944147a7db.png)
![img](https://img-blog.csdnimg.cn/img_convert/b498362cce8806041c319b4e2e4e2381.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
再加 6时。此时我们的坐标映射表里有了两个3 3 但其实它们对应的是同一个坐标。故需要去重,排序。
sort(alls.begin(), alls.end());//排序
[外链图片转存中…(img-nWxYD2Ve-1715625242664)]
[外链图片转存中…(img-CRFl4iwD-1715625242665)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!