404.左叶子之和
问题描述
思路
这里是判断左叶子,不是二叉树左侧节点,不能用层序遍历。
那么判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。 如果该节点的左节点不为空,该节点的左节点的 左节点 为空,该节点的 左节点的 右节点为空,则找到了一个左叶子,判断代码如下:
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
//找出一颗树所有的左叶子节点
}
1、递归法
递归的遍历顺序为后序遍历(左右中),因为要通过递归函数的返回值,来累加,求左叶子数值之和。
递归三部曲:
① 确定递归函数的参数和返回值
判断一个树的左叶子节点之和,那么一定要传入树的根节点。
递归函数的返回值为数值之和,所以为 int
。
② 确定终止条件
if (root == NULL)
return 0;
③ 确定单层递归的逻辑
当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。
代码如下:
int leftValue = sumOfLeftLeaves(root->left); // 左
int rightValue = sumOfLeftLeaves(root->right); // 右
// 中
int midValue = 0;
if (root->left && !root->left->left && !root->left->right) {
midValue = root->left->val;
}
int sum = midValue + leftValue + rightValue;
return sum;
整体递归代码如下:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL)
return 0;
int leftValue = sumOfLeftLeaves(root->left); // 左
int rightValue = sumOfLeftLeaves(root->right); // 右
// 中
int midValue = 0;
if (root->left && !root->left->left && !root->left->right) { // 中
midValue = root->left->val;
}
int sum = midValue + leftValue + rightValue;
return sum;
}
};
以上代码精简如下:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL)
return 0;
int midValue = 0;
if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
midValue = root->left->val;
}
return midValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
};
2、迭代法
使用后序遍历,判断条件一样。
代码如下:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
stack<TreeNode*> st;
if (root == NULL) return 0;
st.push(root);
int result = 0;
while (!st.empty()) {
TreeNode* node = st.top();
st.pop();
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
result += node->left->val;
}
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
return result;
}
};
by the way
平时我们解二叉树的题目时,习惯通过节点的左右孩子判断本节点的属性。
而本题, 我们要通过节点的父节点判断本节点的属性。