技术面试核心知识体系梳理
一、矩阵特征值分析
在求解矩阵特征值时,核心步骤是构建并求解特征方程。设矩阵为 A,单位矩阵为 I,特征值为 λ。我们需要计算行列式 det(A - λI) 的结果,并令其等于零。解此多项式方程得到的根(例如 λ₁, λ₂, ..., λₙ),即为该矩阵的所有特征值。随后将每个特征值代回齐次线性方程组,即可求得对应的特征向量。
二、卷积层输出尺寸计算
在处理卷积神经网络(CNN)时,准确计算输出特征图的维度至关重要。假设输入图像的高宽分别为 H 和 W,卷积核的尺寸为 K×K,填充大小为 P,步长为 S。输出通道的高度(H_out)和宽度(W_out)遵循以下通用公式:
H_out = floor((H - K + 2 * P) / S) + 1
W_out = floor((W - K + 2 * P) / S) + 1
其中 floor 函数表示向下取整,确保输出尺寸为整数。
三、算法时间复杂度阶数详解
评估代码执行效率主要依据数据规模增长对运行时间的影响程度。以下是常见的几种量级及其代码表现:
1. 常数阶 O(1)
无论数据量如何增加,代码执行次数保持不变。通常指不包含循环或递归的简单操作序列。
public int calculateConstant(int param1, int param2) {
int sum = param1 + param2;
return sum * 2;
}
2. 对数阶 O(logN)
随着变量规模的缩减,每次迭代处理剩余问题的一半。典型场景包括二分查找或指数递减循环。
public void logarithmicLoop(int target) {
int counter = target;
while (counter > 1) {
counter = counter / 2; // 每次减半,接近对数级别
}
}
3. 线性对数阶 O(nlogN)
当对数阶逻辑在外层循环执行 N 次时出现。常见于高效排序算法如归并排序或快速排序。
public void linearLogarithmic(int n) {
for (int index = 0; index < n; index++) {
int temp = 1;
while (temp < n) {
temp *= 2;
}
}
}
4. 平方阶 O(n²)
典型的嵌套循环结构,外层循环执行 N 次,内层也执行 N 次。常见于冒泡排序或二维数组遍历。
public void quadraticComplexity(int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
processItem(i, j);
}
}
}
void processItem(int x, int y) { /* 操作 */ }
5. 高次阶 O(n³) 及 O(n^k)
原理同上,若存在三层循环嵌套则表现为立方阶。一般而言,超过二次方的复杂度在实际工程中需避免使用,除非问题规模极小。
四、概率统计基础
贝叶斯定理描述了事件 A 在事件 B 发生条件下的后验概率。公式表达为:P(A|B) = [P(B|A) * P(A)] / P(B)。在算法设计中,常用于垃圾邮件过滤等分类问题的先验概率更新。
五、经典算法编程实战
1. 矩阵中的路径搜索(回溯法)
问题描述:给定一个二维字符网格和一个目标单词,判断网格中是否存在该单词的路径。路径可以从任意位置开始,每次移动只能向上下左右四个方向之一,且同一个格子不能重复访问。
实现思路:采用深度优先搜索(DFS)配合回溯标记。
public class MatrixPathFinder {
private boolean[][] visited;
private int rows;
private int cols;
private static final int[] dx = {-1, 1, 0, 0};
private static final int[] dy = {0, 0, -1, 1};
public boolean exist(char[][] board, String word) {
rows = board.length;
cols = board[0].length;
visited = new boolean[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (dfs(board, word, 0, i, j)) {
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board, String target, int idx, int r, int c) {
if (idx == target.length()) return true;
if (r < 0 || r >= rows || c < 0 || c >= cols ||
visited[r][c] || board[r][c] != target.charAt(idx)) {
return false;
}
visited[r][c] = true;
boolean found = false;
for (int k = 0; k < 4; k++) {
int nextR = r + dx[k];
int nextC = c + dy[k];
if (dfs(board, target, idx + 1, nextR, nextC)) {
found = true;
break;
}
}
visited[r][c] = false; // 回溯
return found;
}
}
2. 利用 Rand5 生成 Rand7
问题描述:已知有一个能等概率生成 1 到 5 之间整数的函数 rand5(),要求编写一个函数 rand7(),使其等概率生成 1 到 7 之间的整数。
实现思路:利用拒绝采样(Rejection Sampling)方法,扩大取值范围后剔除无法均匀分布的数值。
public class RandomGenerator {
// 模拟 rand5() 的已有函数
public int rand5() {
return (int)(Math.random() * 5) + 1;
}
public int rand7() {
int result;
do {
// 生成 1 到 25 的均匀分布:(rand5() - 1) * 5 + rand5()
result = (rand5() - 1) * 5 + (rand5() - 1) + 1;
} while (result > 21); // 只保留前 21 个数以保证模 7 的均匀性
return (result % 7) + 1;
}
}