513.找树左下角的值
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
一直对回溯算法的传值还是传引用比较疑惑。
而东哥写的递归回溯,一般直接用外部变量,就像下面这样
class Solution {
// 记录二叉树的最大深度
int maxDepth = 0;
// 记录 traverse 递归遍历到的深度
int depth = 0;
TreeNode res = null;
public int findBottomLeftValue(TreeNode root) {
traverse(root);
return res.val;
}
void traverse(TreeNode root) {
if (root == null) {
return;
}
// 前序遍历位置
depth++;
if (depth > maxDepth) {
// 到最大深度时第一次遇到的节点就是左下角的节点
maxDepth = depth;
res = root;
}
traverse(root.left);
traverse(root.right);
// 后序遍历位置
depth--;
}
}
如果不用外部变量,就需要思考一下哪些变量必须传引用,哪些可以传值!
拿力扣513题举例,最大深度一定需要传引用,当前深度可以不传引用,而curVal也一定需要传引用
直接看代码吧,curDepth用值传递,后序位置不需要回溯curDepth–
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int curVal=0;
int maxDepth=0;
dfs(root,maxDepth,0,curVal);
return curVal;
}
void dfs(TreeNode* root,int& maxDepth,int curDepth,int& curVal){
if(root == nullptr)return;
//前序位置
curDepth++;
if(curDepth > maxDepth){
//到最大深度时,遇到的第一个节点就是最左节点
maxDepth = curDepth;
curVal = root->val;
}
dfs(root->left,maxDepth,curDepth,curVal);
dfs(root->right,maxDepth,curDepth,curVal);
//后序位置
//curDepth用值传递,后序位置就不需要回溯,每个递归函数都有自己curDepth
}
};
而curDepth按引用传递一定需要回溯!
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int curVal=0;
int maxDepth=0;
int curDepth=0;
dfs(root,maxDepth,curDepth,curVal);
return curVal;
}
void dfs(TreeNode* root,int& maxDepth,int &curDepth,int& curVal){
if(root == nullptr)return;
//前序位置
curDepth++;
if(curDepth > maxDepth){
//到最大深度时,遇到的第一个节点就是最左节点
maxDepth = curDepth;
curVal = root->val;
}
dfs(root->left,maxDepth,curDepth,curVal);
dfs(root->right,maxDepth,curDepth,curVal);
//后序位置
curDepth--;
}
};
此题还可以使用层序遍历,有两种思路:
第一种思路:常规的层序遍历,把每层的第一个节点(最左节点)记录到curVal,遍历完,curVal记录的就是最后一层的最左节点
第二种思路:从右往左的层序遍历,层序遍历的最后一个节点就是最大深度最左节点
第一种思路
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int curVal = 0;
bfs(root,curVal);
return curVal;
}
void bfs(TreeNode* root,int& curVal){
if(root == nullptr)return;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()){
int sz = que.size();
for (int i = 0; i < sz; ++i) {
TreeNode* node = que.front();
que.pop();
if (i==0){
curVal = node->val;
}
if (node->left){
que.push(node->left);
}
if(node->right){
que.push(node->right);
}
}
}
}
};
第二种思路
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int curVal = 0;
bfs(root,curVal);
return curVal;
}
void bfs(TreeNode* root,int& curVal){
if(root == nullptr)return;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()){
TreeNode* node = que.front();
que.pop();
curVal = node->val;
if (node->right){
que.push(node->right);
}
if(node->left){
que.push(node->left);
}
}
}
};