今天阿里笔试,发现自己递归比较薄弱,今天刷递归!加油~
算法题(牛客网)
1. 岛屿数量
DFS,发现一个岛屿的角就将该岛屿全部变为#,发现几次就说明有几个岛屿。
代码详情:
class Solution {
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
vector<int> direction = {1,0,-1,0,1}; //移动方向
int solve(vector<vector<char> >& grid) {
// write code here
int island = 0; //记录岛屿数
for(int i = 0;i < grid.size();++i){ //循环遍历岛屿
for(int j = 0;j < grid[0].size();++j){
if(grid[i][j] == '1'){
DFS(grid,i,j);
++island;
}
}
}
return island;
}
//辅函数-深度优先搜索
void DFS(vector<vector<char> >& grid,int x,int y){
for(int k = 0;k < 4; ++k){
int i = x + direction[k], j = y + direction[k+1];
if(i >= 0 && j >= 0 && i < grid.size() && j < grid[0].size() && grid[i][j] == '1'){
grid[i][j] = '#'; //修改标志代表已遍历
DFS(grid,i,j); //递归
}
}
return;
}
};
2. 二叉树的最大深度
用队列层序遍历我会,但使用DFS第一次使用。
代码详情:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
int maxDepth(TreeNode* root) {
// write code here
if (!root) return 0; //边界判断
return DFS(root,1);
}
//辅函数
int DFS(TreeNode* node, int depth){
if (!node){ //边界判断
return depth-1;
}
int depth_l = DFS(node->left,depth+1); //遍历左子树
int depth_r = DFS(node->right,depth+1); //遍历右子树
return max(depth_l,depth_r);
}
};
3. 判断是不是平衡二叉树
发现使用上一题的递归搜索深度可以解决。
代码详情:
class Solution {
public:
bool flag = true; //标志-true代表是平衡二叉树,则相反
bool IsBalanced_Solution(TreeNode* pRoot) {
DFS(pRoot,1);
return flag;
}
//辅函数-DFS
int DFS(TreeNode* pNode, int depth){
if (!pNode || !flag){ //边界判断
return depth-1;
}
int depth_l = DFS(pNode->left,depth+1); //递归左子树
int depth_r = DFS(pNode->right,depth+1); //递归右子树
if (abs(depth_l - depth_r) > 1){
flag = false;
}
return max(depth_l,depth_r); //返回最深子树深度
}
};
4. 二叉树根节点到叶子节点的所有路径和
一边递归遍历一遍保存路径,最后计算路径和。后面我又优化了一下,一遍遍历一遍计算,就不用保存了。
代码详情:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
int sum = 0; //存储所有路径数字
int sumNumbers(TreeNode* root) {
// write code here
DFS(root,0);
return sum;
}
//辅函数DFS
void DFS(TreeNode* root,int num){
if (!root) return;
num = num * 10 + root->val; //保存当前数字
if (!root->left && !root->right){
sum += num; //已遍历完一条路径,保存
return;
}
DFS(root->left, num); //遍历左子树
DFS(root->right, num); //遍历右子树
return;
}
};
5. 判断一棵二叉树是否为搜索二叉树和完全二叉树
写了一小时还是没写出来,明天再继续写。
面试题(计算机网络篇)
1. 自我介绍(游戏客户端开发)
HR你们好,我叫zzw,21岁,来面试客户端开发,就读于广东工业大学数字媒体技术专业,是一名热爱玩游戏又热爱开发游戏的网瘾少年,学习课程的游戏开发作业,都是完全负责程序代码方面,当然我也喜欢参与策划,课外也热爱自己捣鼓游戏开发,自己开发过几款游戏demo,剪成视频上传到B站,最满意的一款demo就是雷霆战机,播放量过万。开发游戏时喜欢思考如何使游戏更流畅更自然,舒服的游戏体验是我的原则。
除了游戏,现实中我也非常热爱运动,有一部分是因为健康的体魄可以让我更好的与游戏打交道,每天都会去跑步,时不时和朋友一起打篮球,之前爱好街舞,大二还担任了一年的舞蹈俱乐部社长,举办过不少活动,荣获四星级社团。
之所以选择游戏客户端开发,因为很想从事游戏相关的职业,特别喜欢将想法转换成现实这个过程,享受这种成就感,对于游戏自身,好的游戏体验是我一直追求的方向,所以我想带着兴趣和梦想来担任这份工作,以上就是我的自我介绍,谢谢聆听。
2. TCP协议
源端口号/目的端口号:记录数据来源和去处。
序列号:建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机,每发送一次数据,就累加一次。从而解决网络包乱序问题。
确认应答号:确认收到数据,解决不丢包问题。
6位标识符:
URG:紧急指针是否有效
ACK:确认是否有效,该位为1时,确认字段有效。
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走。
RST:对方要求重新建立连接;携带RST标识的称为复位报文段,该位为1时,表示TCP连接中出现异常必须强制断开连接。
SYN:请求建立连接;携带SYN标识的称为同步报文端,该位为1时,表示希望建立连接,并在其序列号的字段进行序列号初始值设定。
FIN:通知对方准备断开连接,携带FIN标识的称为结束报文段,该位为1时,表示准备断开连接。
今天阿里笔试很难,因为我准备的是客户端开发,而这是测试岗位,岗位不匹配,导致笔试困难。之前以为4399没了,他们也发了不通过的邮件,结果今天居然发了面试邮件,神奇,难道真的越努力越幸运嘛!