准备面试杂总
1.求整数序列中的中位数。
//首先想到的是先排序,后直接就求出来了
//参照这位大佬:https://blog.csdn.net/cpu_12593/article/details/48231213 有种恍然大悟的感觉
//洛谷1168题就是
Ⅰ。利用快排查找关键字,随机选取一个关键字进行划分,第一次划分的结果标记位置如果小于N/2,那么就将右半的部分再执行一次这个算法(从选关键字开始);如果关键字位置大于N/2,就将其左半部分在执行这个算法;直到关键字标记位置=N/2,才结束。这样的时间复杂度就是O(n),获取中位数时间为O(1).
Ⅱ。利用数据结构平衡二叉树(左右两颗子树的高度≤1,并且是递归定义的,左子树小于根节点,右子树相反。常用实现方法有红黑树,AVL树,treap树),每读取一个那么久插入到树中,最终根节点就是中位数,但是二叉树的插入调整算法比较复杂。时间复杂度为O(nlogn),获取时间复杂度是O(n),或者是通过查找根节点,用数组来表示的?
Ⅲ。参照这个:https://blog.csdn.net/yhf_2015/article/details/52315689 代码写的真厉害
利用堆来实现。左边是大顶堆,右边是小顶堆,小顶堆中元素永远要么和大顶堆中元素个数相同,要么比它多一个。也就是说将其平分为两部分。
当有元素插入时,如果两堆中元素个数相同,那么就尝试插入小顶堆中,插入的时候需要考虑,如果要插入的元素比小顶堆堆顶的元素小,那么就把大顶堆堆顶的元素插入到小顶堆中,并且将新元素插入的大顶堆中(都是为了保持数量关系。)。否则直接插入小顶堆。
如果两堆中元素个数不同(肯定是小顶堆中元素多了一个),那么就尝试加入大顶堆中,如果新元素比大顶堆堆顶元素大,那么就把小顶堆堆定元素挪过来,并且将新元素插入小顶堆。否则直接插入大顶堆。
//但是有没有这种情况就是把一个根去了之后,仍然仍然是不满足条件,那还接不接着挪点了?
#include <bits/stdc++.h> using namespace std; const int maxn = 100010; int a1[maxn]; int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%d", &a1[i]); priority_queue <int> q1;//优先队列默认是less,大顶堆。 priority_queue <int, vector<int>, greater<int> > q2;//greater小顶堆 int size1 = 0, size2 = 1; q2.push(a1[1]);//先放进 for(int i = 2; i <= n+1; i ++){ if(!(i&1))printf("%d\n", q2.top());//如果i是偶数的话,那么就打印小顶堆的堆定元素 //。比如说现在该查第4个数,那么前三个数中肯定是最小堆堆定元素是中位数。满足了题目要求。 if(i > n) break; if(size2 > size1){ if(a1[i] > q2.top()){ q1.push(q2.top()), size1 ++; q2.pop(); q2.push(a1[i]); }else q1.push(a1[i]), size1 ++; }else{ if(a1[i] < q1.top()){ q2.push(q1.top()), size2 ++; q1.pop(); q1.push(a1[i]); }else q2.push(a1[i]), size2 ++; } } return 0; }//太厉害了
//真厉害,直接用优先队列就可以实现啊,没想到。。学习了。
2.c++中new和malloc的区别。
//真没考虑过这个问题。都是把数据分配在堆区。
参考这个:https://blog.csdn.net/linux_ever/article/details/50533149
Ⅰ。申请内存所在的位置。malloc是分配在堆中,new:自由存储区(那么可否为堆呢?要根据operator new的实现来,其中参数是一个指针,可以指向堆或静态区,在其处分配内存。或者甚至可以不分配内存)
Ⅱ。返回类型安全性。malloc返回是void*类型指针,需要进行强制类型转换;new返回的是严格匹配对象类型的指针,不用强制类型转换,是安全的。
Ⅲ。内存分配失败后返回值不同。malloc会返回NULL,而new则返回bac_alloc。
Ⅳ。是否需要指定内存大小。new不需要。malloc需要制定。
Ⅴ。是否调用析构函数。使用new/delete会调用对象的构造函数和析构函数。但是malloc不会。
//先写着几点吧,写多了也记不住。
3.堆和栈有什么区别?
//堆中是通过malloc分配的,栈是存储普通的类型变量,从低地址开始分配。其他的就像不知道了。
参考这位大佬:https://www.cnblogs.com/mysticCoder/p/4921724.html
栈的分配是由操作系统控制的,一般存放函数的局部变量等,使用完立即由操作系统释放。
堆是通过程序员手动申请和释放的,如果没有,则程序结束后由OS自动回收。
堆中内存分分配容量比栈中大,说来也是,一些大的高位数组,直接普通定义不行,可以用new那么就可以了。
碎片的问题:堆中会产生,但是栈是连续分配的不会产生,
生长方向:堆是向上生长即向着内存增加的方向;但是栈是相反的,是向着内存减小的方向。
分配效率:当然是栈高了。堆还需要调用一系列的算法来实现。
4.什么是随机变量?
//就是随机生成的变量,比如java中用random生成,可以给它种子。不过这是概率论的知识吗?emmm
简单的说就是随机事件的数量表现。包括离散性(伯努利概型)、连续性随机变量(指数随机变量)等。参考:百度百科随机变量定义。
在一定条件下,并不一定出现相同结果的现象称谓为随机现象,其结果称为随机变量,比如任意时刻车站的人数。