准备面试杂总

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

简单的说就是随机事件的数量表现。包括离散性(伯努利概型)、连续性随机变量(指数随机变量)等。参考:百度百科随机变量定义。

 在一定条件下,并不一定出现相同结果的现象称谓为随机现象,其结果称为随机变量,比如任意时刻车站的人数。 

原文地址:https://www.cnblogs.com/BlueBlueSea/p/9245948.html