题目
原题链接
计算给定二叉树的所有左叶子之和。
示例:
3
/ \
9 20
/ \
15 7
在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
思路一 · 递归
该题细节较多,有些看似不重要的特判语句,不加则会导致程序不够严谨,致使答案或编译出错,以下代码注释中有写“不加会出错”的就是这类语句。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int sum;
int sumOfLeftLeaves(TreeNode* root) {
if(!root) return 0; //判断该树是否为空,不加会出错
digit(root); //调用递归函数更新sum返回值
return sum;
}
void digit(TreeNode* node) {
if(node == NULL) return; //该节点为空直接返回,不加会出错
if(check(node)) return; //如果该节点为叶子节点,直接返回,不加会出错
if(node -> left) //特判左儿子是否为空,不加会出错
if(check(node -> left)) { //如果该节点的左儿子是叶子节点
sum += node -> left -> val; //加入sum里头去
digit(node -> right); //只要递归右节点即可
return;
}
digit(node -> right); //递归检验左儿子
digit(node -> left); //递归检验右儿子
}
bool check(TreeNode* node) { //返回是(true)否(false)为叶子节点
if(node -> right == NULL && node -> left == NULL) return true;
//左右儿子都为空才是叶子节点
else return false; //否则就不是
}
};
思路二 · 非递归(队列实现)
我们知道,左叶子节点需要满足两个条件:
——第一,是父亲节点的左儿子
——第二,是一个叶子节点,为了更好地在代码里表示,我们理解为:没有左右儿子。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int sum;
int sumOfLeftLeaves(TreeNode* root) {
if(!root) return 0; //判断该树是否为空,不加会出错
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
TreeNode* t = q.front();
q.pop();
//以下分两个分支,一个压入左子树,另一个压入右子树。
if(t -> left) { //题目要求的左叶子只可能在这个分支产生
if(!t -> left -> left && !t -> left -> right)
//确保是叶子节点,关于他是左儿子的条件已在之前体现
sum += t -> left -> val;
q.push(t -> left); //压入左儿子
}
if(t -> right)
q.push(t -> right);//压入右儿子
}
return sum;
}
};