系列综述:
目的:本系列是个人整理为了秋招面试
的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
来源:材料主要源于【CodeTopHot200】进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证,所有代码均优先参考最佳性能。
结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢!!!
【C++】秋招&实习面经汇总篇
点此到文末惊喜↩︎
if (root->left/rihgt)
,因为递归出口已经判断了// 前序遍历
void Traversal(TreeNode *root) {
if (root == nullptr) return ;
Doing(root->val); // 中
Traversal(root->left); // 左
Traversal(root->right); // 右
}
// 中序遍历
void Traversal(TreeNode *root) {
if (root == nullptr) return ;
Traversal(root->left); // 左
Doing(root->val); // 中
Traversal(root->right); // 右
}
// 后序遍历
void Traversal(TreeNode *root, vector<int> vec) {
if (root == nullptr) return ;
Traversal(root->left); // 左
Traversal(root->right); // 右
vec.emplace_back(root->val);// 中
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res; // 结果容器
stack<TreeNode*> st; // 深度栈
if(root != nullptr) st.push(root); // 根非空则入栈
// 遍历源容器
while (!st.empty()) { // key:注意使用的全部结点都是node
// 先记录
TreeNode *node = st.top();
st.pop();
// 后操作
if (node != nullptr) {
// 压入允许为逆序,注意根节点要后压入nullptr
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
st.push(node);
st.push(nullptr);
} else {
// 先记录
node = st.top();
st.pop();
// 后操作
res.emplace_back(node->val);
}
}
return res;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
// 递归出口:返回标志,不为空说明是祖先结点
if (root == p || root == q || root == nullptr)
return root;
// 后序遍历
TreeNode *left = lowestCommonAncestor(root->left, p, q);
TreeNode *right = lowestCommonAncestor(root->right, p, q);
// 中间结点的处理
// 左右都非空表示,该节点为公共祖先结点
if (left != nullptr && right != nullptr)
return root;
// 有一个为空表示,
if (left == nullptr) return right;
if (right == nullptr) return left;
return root;
}
// 初始化ans为true,最后看ans是否为false即可
int depth(TreeNode* root, bool &ans) {
if(!root) return 0;
// 后序遍历
int left=1+depth(root->left, ans);
int right=1+depth(root->right, ans);
if(abs(left-right) > 1) ans = false;// 对根结点的处理
// 递归出口
return max(left,right); // 返回树的高度
}
// 尾递归优化:效率高
bool isBalanced(TreeNode* root) {
if (root == nulllptr) return true;
return abs(depth(root->left) - depth(root->right)) <= 1
&& isBalanced(root->left)
&& isBalanced(root->right);
}
int getNodesNum(TreeNode* cur) {
if (cur == NULL) return 0;
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
}
TreeNode* invertTree(TreeNode* root) {
auto self = [&](auto &&self, TreeNode *root){
if (root == nullptr) return ;
self(self, root->left);
self(self, root->right);
swap(root->left, root->right);
return ;
};
self(self, root);
return root;
}
bool isSymmetric(TreeNode* root) {
auto self = [&](auto && self, TreeNode *left, TreeNode *right)->bool{
// 递归出口
if (left == nullptr && right == nullptr) return true;
else if (left != nullptr && right == nullptr) return false;
else if (left == nullptr && right != nullptr) return false;
else if (left->val != right->val) return false;
// 后序遍历:递归比较并汇总结果
bool outside = self(self, left->left, right->right);
bool inside = self(self,left->right, right->left);
bool is_same = outside && inside;
// 返回结果
return is_same;
};
return self(self, root->left, root->right);
}
if (node->left != nullptr
&& node->left->left == nullptr
&& node->left->right == nullptr)
res += node->left->val;
to_string(number)
str.append(subStr)
str.erase(position)
// 数字型
void dfs(TreeNode*root,vector<int>path, vector<vector<int>> &res) {
if(!root) return; //根节点为空直接返回
// 中
path.push_back(root->val); //作出选择
if(!root->left && !root->right) //如果到叶节点
{
res.push_back(path);
return;
}
// 左
dfs(root->left,path,res); //继续递归
// 右
dfs(root->right,path,res);
}
// 字符型
void binaryTree(TreeNode* root,string path,vector<string>&res) {
if(root==NULL) return ;
path.append(to_string(root->val));
path.append("->");
if(root->left==NULL&&root->right==NULL{
path.erase(path.length()-2);
res.push_back(path);
}
binaryTree(root->left,path,res);
binaryTree(root->right,path,res);
}
vector<string> binaryTreePaths(TreeNode* root) {
string path;
vector<string>res;
binaryTree(root,path,res);
return res;
}
// 递归方式:前序遍历,并记录每条路径的和
bool hasPathSum(TreeNode* root, int targetSum) {
bool flag = false;
auto self = [&](auto &&self, TreeNode *root, int sum){// sum不可全局
if (root == nullptr) return ;
// 根结点的处理
sum += root->val;
cout << sum << ' ';
if (root->left == nullptr && root->right == nullptr
&& targetSum == sum)
flag = true;
self(self, root->left, sum);
self(self, root->right, sum);
};
self(self, root, 0);
return flag;
}
// 非递归
bool hasPathSum(TreeNode* root, int targetSum) {
// 初始化
stack<TreeNode*> st;
if(root != nullptr) st.push(root);
int sum = 0;
// 迭代
while(!st.empty()){
TreeNode *cur = st.top();
if(cur != nullptr){
st.pop();
st.push(cur);
st.push(nullptr);
sum += cur->val;
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}else{
st.pop();
cur = st.top();
st.pop();
// 节点判断
if(sum == targetSum&& cur->left == nullptr
&& cur->right == nullptr){
return true;
}else{// 回溯
sum -= cur->val;
}
}
}
return false;
}
点此跳转到首行↩︎