数据结构简介、前缀和、对数器
数据结构简介
1.数据结构是存储、组织数据的方式
2精心选择的数据结构可以带来更高的运行或者存储效率
3.数据结构是很多算法得以进行的载体
最基本的数据结构
1.数组
便于寻址,不便于增删数据
2.链表
便于增删数据,不便于寻址
前缀和
1.前缀和介绍
前缀和,顾名思义,就是前n项相加之和,和我们高中时候学习的数列中的一个含义,例如一个等差数组=n,那他的前n项和= ,也可知道-=
前缀和的应用有很多,例如我们现在有一个方法sum(array,L,R),就是调用此方法求出一维数组 [3,4,2,1,6,7,8]的前缀和,调用次数非常频繁,我们不能每次都通过遍历数组去求和,这样太慢,我们可以采用预处理,加快查询速度
第一种、预处理方法,建立一张正方形的表,提前将所有的前缀和结果存入其中
优点:查询速度很快 缺点:建立表的过程繁琐
因此我们引出第二种预处理方法:前缀和数组
2.一维数组的前缀和
对于一维数组而言,所谓前缀和,顾名思义,就是当前位置及之前元素的总和。假设有数组 A=[1,2,3,4,5,6,7]
为原数组,有数组 B作为A的前缀和数组,那么B=[1,3,6,10,15,21,28]
;可以发现B[i] = A[0]+....+A[i]
,即B[i]
是数组A的前面i个数的总和。
因此有了前缀和数组可以简化我们算法就子区间和,假设没有前缀和要求数组A区间[2,4]的总和,我们需要从 i=2 遍历 到 i=4 ,时间复杂度为O(n),通过前缀和只需要计算 B[4]-B[1]即可
也就是说当L==0时,求数组A[ 0~R ] 的总和,就是B[R] ;当L != 0时,求数组A[ L~R ] 的总和,就是B[ R ] - B[ L ]
优点 :查询速度也快,建立简单,但如果查询次数特别多(上亿次)的情况下,第一种直接返回的方式更快
//生成前缀和数组
public int[] prefix(int[] nums) {
int[] prefix = new int[nums.length];
prefix[0] = nums[0];
for (int i = 1; i < nums.length; ++i) {
prefix[i] = prefix[i - 1] + nums[i];
}
return prefix;
}
//查询
public int rangeSum(int L ,int R){
return L == 0 ? prefix[R] : prefix[R] - prefix[L - 1] ;
}
对数器
在说对数器是什么之前,相信很多人都去力扣上刷过算法题,在提交代码的时候,系统会给很多组测试用例,这些测试用例全部都通过了你的代码才算是正确的。对数器就是类似于这样的一个检测你的代码是否正确的系统。
1.起源介绍 —>随机函数
Java中的Math .Random()函数
会等概率返回一个范围在[ 0 , 1 )的double类型的小数
public class Rng {
public static void main(String[] args){
//Math.random() -->double -->[0,1)
int testTimes = 10000000;
int count = 0;
for (int i = 0; i < testTimes; i++) {
if (Math.random() < 0.3){
count++;
}
}
//真实出现的次数/总次数--->证明确实等概率返回
System.out.println((double) count / (double) testTimes);
//如何改变返回数的范围[0,1)--->[0,8)只用把 Math.random() * 8
System.out.println("=========");
count = 0;
for (int i = 0; i < testTimes; i++) {
if (Math.random() * 8 < 5) {
count++;