面试笔试中的重要算法合集

基础算法

1.快速排序(超级重要,手撕)

  • 可能会有“第K个数”的改编

2.归并排序(一般重要)

“逆序对的数量”不看

3.二分

笔试多,面试不多
只看“数的范围”

4.高精度

看个加法就可以了

5.前缀和与差分

  • 前缀和(最重要)
  • 子矩阵的和(二维的)
  • 差分(一般重要)

6.双指针算法(超级重要)

面试,笔试会问

7.位运算

其他题可能会用到

8.区间合并

超级重要,面试会问

数据结构

1.栈

看“表达式求值”就可以了。
或者
看“括号匹配”

2.Trie

面试会问-“大数据量的排序”

3.并查集

笔试中的难题

搜索与图论

1.DFS(最重要)

2.BFS

3.树与图的深度优先遍历-DFS

题目描述:树的重心

给定一颗树,树中包含 n 个结点(编号 1∼n)和 n−1 条无向边。

请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。

输入格式
第一行包含整数 n,表示树的结点数。

接下来 n−1 行,每行包含两个整数 a 和 b,表示点 a 和点 b 之间存在一条边。

输出格式
输出一个整数 m,表示将重心删除后,剩余各个连通块中点数的最大值。

数据范围
1≤n≤105
输入样例
9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6
输出样例:
4

代码

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

// N代表节点数量, M代表边的数量,树是无向连通图
const int N = 100010, M = N * 2;

int ans = N; // 定义答案
// 注意一条边有两个节点
int h[N];//表示第i个节点的 第一条边的 idx
int e[M]; // 表示 第 idx条边的 end节点下标
int ne[M]; // 表示与第idx条边 同一起点的节点的下一条边的idx
int idx; // 边的下标索引
bool st[N]; // 存放该点是否已被遍历的状态数组

int n;

// 树的深搜,返回的是去掉u节点后剩余连通图中节点的最大值
int dfs(int u){
    
    
    st[u] = true; // 标记该点已被遍历
    
    int sum = 1; // 当前子树(连通块)所具备的节点数量,初始为1
    int res = 0; // 初始化 将该点删除后剩余连通块的点数的max
    
    // 遍历以u开始的链表的所有边
    for(int i = h[u]; i != -1; i = ne[i]){
    
    
        int j = e[i]; // 获取该边的end节点的下标
        // 如果该点没有被遍历过,就遍历他
        if(st[j]) continue;
        else{
    
    
            int s = dfs(j);
            // 记录所有连通块的最大值
            res = max(res, s);
            sum += s; // 当前遍历到的子树的max是u的树的一部分
        }
    }
    res = max(res, n - sum);//n-sum代表u节点父节点以上的连通块中节点数量
    ans = min(ans, res);
    return sum;
}

// 添加一条边,该边的起点下标是a,终点下标是b
void add(int a, int b){
    
    
    e[idx] = b; // 该边的下标应该是idx,将该边的终点节点 记成 b
    ne[idx] = h[a]; // 由于每个节点都会以其为头创建一个链表,将该边插入到a节点开头
    h[a] = idx ++; // 将a节点的链表的头指向当前的边,并将边的下标++,准备指向下一条边
}

int main(){
    
    
    memset(h, -1, sizeof h);
    // 处理输入输出
    cin >> n;
    for(int i = 0; i < n - 1; i ++){
    
    
        // 添加一条边
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }
    dfs(1);
    cout << ans << endl;
    return 0;    
}

4.树与图的广度优先遍历-BFS

5.拓扑排序

笔试会考,面试一般不会

6.Kruskal

笔试会考

动态规划

“状态压缩”不看
数位统计不看
背包和线性DP最重要

数学知识

1.质数-“判定质数”

2.约数中的“最大公约数”

贪心

1.先看“排队打水”

2.基础算法中的区间合并

3.Huffman树

4.货仓选址

猜你喜欢

转载自blog.csdn.net/weixin_43943476/article/details/127448839