系列综述:
💞目的:本系列是个人整理为了
秋招面试
的,整理期间苛求每个知识点,平衡理解简易度与深入程度。🥰来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢🎈🎄🌷!!!
文章目录
打表法
-
打表
- 作用:如果程序的值具有固定可接受的范围,可以通过计算每个值对应解,并形成一张表。从而提高计算速度
- 方法:通过暴力方法打印尽可能多组映射示例,然后针对这多组映射示例推导规律,定制简单的算法
- 方向
- 笔试打表:可以直接通过5个左右的示例进行纸上暴力手动打表,找不出来再代码打表
- 面试/工作:向面试官讲明原理,然后表示自己会进行完整的测试
- 特点:
- 输入参数类型简单,并且只有一个实际参数
- 返回值类型简单,并且只有一个
- 通过暴力方法将输入与返回值的对应关系打印出来,并优化
- 步骤:
- 编写简单的暴力方法,并打印多组示例的对应关系
- 针对该多组示例的对应关系进行规律的查找,然后
面向规律
编程
-
打表法
示例1- 小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量。
- 1)能装下6个苹果的袋子
- 2)能装下8个苹果的袋子
- 小虎可以自由使用两种袋子来装苹果,但是小虎有强迫症,他要求自己使用的袋子数量必须最少,且使用的每个袋子必须装满。
- 给定一个正整数N,返回至少使用多少袋子。如果N无法让使用的每个袋子必须装满,否则返回-1
- 小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量。
-
打表法
示例2- 定义一种数:可以表示成若干(数量>1)连续正数和的数,比如:
- 5= 2+3, 5就是这样的数
- 12 = 3+4+5, 12就是这样的数
- 1不是这样的数,因为要求数量大于1个、连续正数和
- 2= 1 + 1,2也不是,因为等号右边不是连续正数
- 给定一个参数N,返回是不是可以表示成若干连续正数和的数
- 判断num是不是2的某次方
(num & (num - 1)) == 0
是2的某次方(num & (num - 1)) !=0
不是2的某次方
- 定义一种数:可以表示成若干(数量>1)连续正数和的数,比如:
矩阵处理
- 矩阵特殊轨迹问题
- 宏观调度法:
- 示例1:zigzag打印矩阵
- 将打印轨迹进行分解:实际是每次打印一条A点和B点之间的斜线
- 将打印轨迹进行分解:实际是每次打印一条A点和B点之间的斜线
cpp
void printMatrixZigZag(vector<vector<int>> matrix) {
// 打印斜线
auto print_bias = [&matrix](int Ar, int Ac, int Br, int Bc, bool direction) {
if(direction) {
while(Ar!=Br+1) {
cout << matrix[Ar++][Ac--] << " ";
}
}else {
while(Br!=Ar-1) {
cout << matrix[Br--][Bc++] << " ";
}
}
};
// 主函数部分
int Ar = 0;// A点和B点的坐标
int Ac = 0;
int Br = 0;
int Bc = 0;
int endR = matrix.size()-1; // 边界
int endC = matrix[0].size()-1;
bool fromUp = false;
while(Ar != endR+1) { // 结束条件:A的行坐标为下边界值+1
print_bias(Ar,Ac,Br,Bc,fromUp);
Ar = Ac==endC?Ar+1:Ar; // A点到最后一列时,Ar开始下移
Ac = Ac==endC?Ac:Ac+1; // A点没到最后一列时,Ac右移
Bc = Br==endR?Bc+1:Bc;
Br = Br==endR?Br:Br+1;
fromUp = !fromUp; // 方向交叉
}
}
- 示例2:转圈打印矩阵
- 子过程:每次顺时针打印一圈,
cpp
template<typename T>
void pirntEdage(std::vector<std::vector<T>>& my_matrix, int tR, int tC, int dR, int dC) {
if (tR == dR) { // 行相同
for (int i = tC; i <= dC; ++i) {
std::cout << my_matrix[tR][i] << ",";
}
} else if (tC == dC) { // 列相同
for (int i = tR; i <= dR; ++i) {
std::cout << my_matrix[i][tC] << ",";
}
} else { // 打印四条边
int curR = tR;
int curC = tC;
while (curC != dC) {
std::cout << my_matrix[tR][curC] << ",";
++curC;
}
while (curR != dR) {
std::cout << my_matrix[curR][dC] << ",";
++curR;
}
while (curC != tC) {
std::cout << my_matrix[dR][curC] << ",";
--curC;
}
while (curR != tR) {
std::cout << my_matrix[curR][tC] << ",";
--curR;
}
}
}
template<typename T>
void spiralOrderPrint(std::vector<std::vector<T>>& my_matrix) {
int tR = 0;
int tC = 0;
int dR = my_matrix.size() - 1;
int dC = my_matrix[0].size() - 1;
while (tR <= dR && tC <= dC) {
pirntEdage(my_matrix, tR++, tC++, dR--, dC--);
}
}
- 示例2:原地旋转正方形矩阵
- 子过程:每次旋转一层
cpp
void Rotate(vector<vector<int>> matrix) {
// 旋转一圈
auto rotate_edge = [&matrix](int a, int b, int c, int d){
int tmp = 0;
// 每一圈一共执行d-b次
// 每次顺时针交互对应的四个元素
for (int i = 0; i < d-b; ++i) {
tmp = matrix[a][b+i];
matrix[a][b+i] = matrix[c-i][b];
matrix[c-i][b] = matrix[c][d-i];
matrix[c][d-i] = matrix[a+i][d];
matrix[a+i][d] = tmp;
}
};
// 主逻辑
int a = 0;
int b = 0;
int c = matrix.size()-1;
int d = matrix[0].size()-1;
while (a < c) {
rotate_edge(matrix, ++a, ++b, --c, --d);
}
}
少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。 不如点赞·收藏·关注一波