题目:
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
递归方法:
三种解法:第一种解法直接排除
①:前序遍历遍历每一个节点,到左节点无孩子则赋深度和值。这个还要分情况很复杂(比如无左孩子,有右孩子且为叶子那么此时就选择右孩子)等。不考虑。
②:代码随想录三步走,但是思维不清晰。
1:思考问题(最底层、最左边)
2:解决问题(找到每一个左叶子比较深度)
3:递归三部曲:确定递归函数的参数和返回值、确定终止条件(即主代码:满足问题的情况)、确定单层递归的逻辑
③:按递归函数来看(整体来看:即根的情况、左树的情况、右树的情况)
分为:
1:根为叶子。
2:根不为叶子,查找左子树左下角的值,或者右子树左下角的值。
②③解法可以结合成一种解法:思考时用②的1、2写代码用③。
运用②③结合的方法更简便,思考到答案更快。
怎么只取一行的左边第一个值:
首先要先遍历左边再遍历右边,遍历一行的左边第一个之后,条件是 lenth > maxlen 所以后面的都排除掉了。
思考递归问题方式:
一:思考问题(最底层、最左边)
二:解决问题(找到每一个左叶子比较深度)
三:递归三部曲:
1:确定递归函数的参数和返回值、
2:确定终止条件(即主代码:满足问题的情况)、有时候满足问题的情况不明确(如:通过中序后序来构建树),此时直接第三步,分为根节点,左子树,右子树来思考。
3:确定单层递归的逻辑
(即遍历顺序、首先思考遍历方式即此题的先序遍历、然后再用方法③即根的情况(即主代码不用思考了)、左树的情况(此时情况写递归函数时用递归函数名字来思考)、右树的情况)
先序遍历思考方法:
先序遍历:左边遍历到达终点,回退一个单位然后走右边。(只思考最后的三个节点即可)。
整体看是:当前节点、左节点、右节点。
细致看是:左节点、右节点、将代码分为了三块:
1:主代码
2:左节点
3:右节点
左右节点进行主代码操作
这其实可以看为遍历一个节点的左右节点
主代码:每个节点执行的代码、一些条件都是在主代码中完成。(如:只选择一行最左边的值赋值(想条件的时候只思考三个节点就行了(根、根左孩子、根右孩子))):
if (root->left == NULL && root->right == NULL) {
if (leftLen > maxLen) {
maxLen = leftLen;
maxleftValue = root->val;
}
return;
}
左右节点:
if (root->left) {
leftLen++;
traversal(root->left, leftLen);
leftLen--; // 回溯
}
if (root->right) {
leftLen++;
traversal(root->right, leftLen);
leftLen--; // 回溯
}
代码:
class Solution {
public:
int maxlength = INT_MIN;
int maxvalue = -1;
void findnode(TreeNode*root, int len ){
if(!root->left && !root->right){
if(len > maxlength) {
maxlength = len;
maxvalue = root->val;
}
return ;
}
if(root->left){
len++
findnode(root->left, len);
len--;
}
if(root->right){
len++;
findnode(root->right, ++len);
len--;
}
return ;
}
int findBottomLeftValue(TreeNode* root) {
findnode(root, 1);
return maxvalue;
}
};
传值过去还是改了当前递归函数的 len
对的:
if(root->left){
len++;
findnode(root->left, len);
len--;
}
错的:
if(root->left){
findnode(root->left, len++);
}
对的:
if(root->left){
findnode(root->left, len + 1);
}
——————————————————————————————————————————————————————
迭代方法:
层序遍历,最后一层第一个元素即是。
将每一层第一个元素入栈,最后出栈顶即是。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
int result = 0;
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if (i == 0) result = node->val; // 记录最后一行第一个元素
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return result;
}
};