【机器学习】【操作系统】【网络】【算法与数据结构】知识汇总

机器学习

L1不可导的时候该怎么办

操作系统

堆栈区别

堆和栈的区别:

一、堆栈空间分配区别:

1)、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;

2)、堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

二、堆栈缓存方式区别:

1)、栈使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放;

2)、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

堆:内存中,存储的是引用数据类型,引用数据类型无法确定大小,堆实际上是一个在内存中使用到内存中零散空间的链表结构的存储空间,堆的大小由引用类型的大小直接决定,引用类型的大小的变化直接影响到堆的变化

栈:是内存中存储值类型的,大小为2M,超出则会报错,内存溢出

三、堆栈数据结构区别:

堆(数据结构):堆可以被看成是一棵树,如:堆排序;

栈(数据结构):一种先进后出的数据结构。

特点:先进后出

栈溢出有哪些情况

1)、局部数组过大。当函数内部的数组过大时,有可能导致堆栈溢出。

2)、递归调用层次太多。递归函数在运行时会执行压栈操作,当压栈次数太多时,也会导致堆栈溢出。3)、指针或数组越界。这种情况最常见,例如进行字符串拷贝,或处理用户输入等等。

算法与数据结构

排序

计数排序/桶排序

时间复杂度 O ( N + K ) O(N+K) O(N+K),用时间换空间,当 O ( k ) > O ( n log ⁡ ( n ) ) O(k)>O(n\log(n)) O(k)>O(nlog(n))时效率不如基于比较的排序

topK给出3种解法

1)局部淘汰法 – 借助“冒泡排序”获取TopK

思路:(1)可以避免对所有数据进行排序,只排序部分;(2)冒泡排序是每一轮排序都会获得一个最大值,则K轮排序即可获得TopK。

时间复杂度空间复杂度:(1)时间复杂度:排序一轮是O(N),则K次排序总时间复杂度为:O(KN)。(2)空间复杂度:O(K),用来存放获得的topK,也可以O(1)遍历原数组的最后K个元素即可。

2)局部淘汰法 – 借助数据结构"堆"获取TopK

思路:(1)堆:分为大顶堆(堆顶元素大于其他所有元素)和小顶堆(堆顶其他元素小于所有其他元素)。(2)我们使用小顶堆来实现。(3)取出K个元素放在另外的数组中,对这K个元素进行建堆。(4)然后循环从K下标位置遍历数据,只要元素大于堆顶,我们就将堆顶赋值为该元素,然后重新调整为小顶堆。(5)循环完毕后,K个元素的堆数组就是我们所需要的TopK。

时间复杂度与空间复杂度:(1)时间复杂度:每次对K个元素进行建堆,时间复杂度为:O(KlogK),加上N-K次的循环,则总时间复杂度为O((K+(N-K))logK),即O(NlogK),其中K为想要获取的TopK的数量N为总数据量。(2)空间复杂度:O(K),只需要新建一个K大小的数组用来存储topK即可

3)分治法 – 借助”快速排序“方法获取TopK

思路:(1)比如有10亿的数据,找处Top1000,我们先将10亿的数据分成1000份,每份100万条数据。(2)在每一份中找出对应的Top 1000,整合到一个数组中,得到100万条数据,这样过滤掉了999%%的数据。(3)使用快速排序对这100万条数据进行”一轮“排序,一轮排序之后指针的位置指向的数字假设为S,会将数组分为两部分,一部分大于S记作Si,一部分小于S记作Sj。(4)如果Si元素个数大于1000,我们对Si数组再进行一轮排序,再次将Si分成了Si和Sj。如果Si的元素小于1000,则我们需要在Sj中获取1000-count(Si)个元素的,也就是对Sj进行排序(5)如此递归下去即可获得TopK。

时间复杂度与空间复杂度:(1)时间复杂度:一份获取前TopK的时间复杂度:O((N/n)logK)。则所有份数为:O(NlogK),但是分治法我们会使用多核多机的资源,比如我们有S个线程同时处理。则时间复杂度为:O((N/S)logK)。之后进行快排序,一次的时间复杂度为:O(N),假设排序了M次之后得到结果,则时间复杂度为:O(MN)。所以 ,总时间复杂度大约为O(MN+(N/S)logK) 。(2)空间复杂度:需要每一份一个数组,则空间复杂度为O(N)。

Hash表处理冲突的方法

apriori

卡特兰数

【算法】震惊!!!史上最详细的卡特兰数浅谈!!!

二分图匹配

布隆过滤器

位图法

红黑树/平衡树

特别大的数据量,实现查找,排序

1)、位图法

位图法是我在编程珠玑上看到的一种比较新颖的方法,思路比较巧妙效率也很高。
使用场景举例:对2G的数据量进行排序,这是基本要求。

数据:1、每个数据不大于8亿;2、数据类型位int;3、每个数据最多重复一次。

内存:最多用200M的内存进行操作。

首先对占用的内存进行判断,每个数据不大于8亿,那么8亿是一个什么概念呢。

**

1 byte = 8 bit(位)

1024 byte = 8*1024 bit = 1k

1024 k = 810241024 bit = 1M = 8388608 bit

**

也就是1M=8388608位

而位图法的基本思想就是利用一位代表一个数字,例如3位上为1,则说明3在数据中出现过,若为0,则说明3在数据中没有出现过。所以当题目中出现每个数据最多重复一次这个条件时,我们可以考虑使用位图法来进行大数据排序。

那么假如使用位图法来进行这题的排序,内存占用多少呢。由题目知道每个数据不大于8亿,那么我们就需要8亿位,占用800000000/8388608=95M的空间,满足最多使用200M内存进行操作的条件,这也是这题能够使用位图法来解决的一个基础。

2)、堆排序法

堆排序是4种平均时间复杂度为nlogn的排序方法之一,其优点在于当求M个数中的前n个最大数,和最小数的时候性能极好。所以当从海量数据中要找出前m个最大值或最小值,而对其他值没有要求时,使用堆排序法效果很好。

使用场景:从1亿个整数里找出100个最大的数

步骤:

(1)读取前100个数字,建立最大值堆。(这里采用堆排序将空间复杂度讲得很低,要排序1亿个数,但一次性只需读取100个数字,或者设置其他基数,不需要1次性读完所有数据,降低对内存要求)

(2)依次读取余下的数,与最大值堆作比较,维持最大值堆。可以每次读取的数量为一个磁盘页面,将每个页面的数据依次进堆比较,这样节省IO时间。

(3)将堆进行排序,即可得到100个有序最大值。

堆排序是一种常见的算法,但了解其的使用场景能够帮助我们更好的理解它。

3)、较为通用的分治策略

分治策略师对常见复杂问题的一种万能的解决方法,虽然很多情况下,分治策略的解法都不是最优解,但是其通用性很强。分治法的核心就是将一个复杂的问题通过分解抽象成若干个简单的问题。

应用场景:10G的数据,在2G内存的单台机器上排序的算法

我的想法,这个场景既没有介绍数据是否有重复,也没有给出数据的范围,也不是求最大的个数。而通过分治虽然可能需要的io次数很多,但是对解决这个问题还是具有一定的可行性的。

步骤:

(1)从大数据中抽取样本,将需要排序的数据切分为多个样本数大致相等的区间,例如:1-100,101-300…

(2)将大数据文件切分为多个小数据文件,这里要考虑IO次数和硬件资源问题,例如可将小数据文件数设定为1G(要预留内存给执行时的程序使用)

(3)使用最优的算法对小数据文件的数据进行排序,将排序结果按照步骤1划分的区间进行存储

(4)对各个数据区间内的排序结果文件进行处理,最终每个区间得到一个排序结果的文件

(5)将各个区间的排序结果合并。通过分治将大数据变成小数据进行处理,再合并。

猜你喜欢

转载自blog.csdn.net/TQCAI666/article/details/114083464