方法思路
本题的难点在于确定什么是左叶子
左叶子就是有左孩子节点,并且这个左孩子节点没有左右孩子
然后利用后序遍历、递归法还是层序遍历做都可以
方法一:后序遍历之递归法
首先写出二叉树的后序遍历(递归法):
public void postTraval(TreeNode root,List<Integer> result){
if (root == null){
return;
}
postTraval(root.left,result);
postTraval(root.right,result);
result.add(root.val);
}
在此基础上进行修改
1、递归的参数和返回值:参数就是需要处理的节点,返回值就是计算得到的左叶子节点之和
2、递归的终止条件:当要处理的节点是空的话,就返回0
3、单层递归逻辑:对于一个节点,先处理得到左子树的所有左叶子节点之和,也就是递归调用在节点的左孩子(sumOfLeftLeaves(node.left)),再得到右子树的所有左叶子节点之和,也就是递归调用在节点的右孩子(sumOfLeftLeaves(root.right)),然后再处理自己,是否有左叶子节点可以相加,然后左叶子节点总和就是这3个数值相加。
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) return 0;
int leftsum = sumOfLeftLeaves(root.left); //左子树的左叶子节点之和
int rightsum = sumOfLeftLeaves(root.right); //右子树的左叶子节点之和
if (root.left != null && root.left.left == null && root.left.right == null){
leftsum = root.left.val;
}
int sum = leftsum + rightsum;
return sum;
}
方法二:先序遍历之迭代法
先写出先序遍历的迭代法代码:
//迭代法
//需要借助一个栈
//遍历顺序:中-左-右 入栈顺序:中 右 左 出栈顺序:中 左 右 先中进 中出 右进 左进 左出 右出
public List<Integer> preorderTraversal1(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if (root == null){
return result;
}
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop(); //要访问的节点就是要处理的节点
result.add(node.val);
if (node.right != null){
stack.push(node.right);
}
if (node.left != null){
stack.push(node.left);
}
}
return result;
}
因此可以看出,只要对于每次出栈的节点进行一个判断,是否有左叶子节点就可以了,代码如下:
//2、迭代法-先序遍历
//先序遍历的迭代法需要借助一个栈来完成,遍历顺序:中左右 入栈顺序:中右左
public int sumOfLeftLeaves1(TreeNode root){
if (root == null) return 0;
int sum = 0;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
if (node.left != null && node.left.left == null && node.left.right == null){
sum += node.left.val;
}
if (node.right != null){
stack.push(node.right);
}
if (node.left != null){
stack.push(node.left);
}
}
return sum;
}
方法三:层序遍历之迭代法
先写出层序遍历的代码:
//迭代法
public List<List<Integer>> levelOrder(TreeNode root) {
//借助一个队列来实现层序遍历
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (root == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (!queue.isEmpty()){
List<Integer> itemList = new ArrayList<>();
int len = queue.size(); //用来记录每一行有多少个节点
while (len > 0){
TreeNode node = queue.poll();
itemList.add(node.val);
if (node.left != null){
queue.add(node.left);
}
if (node.right != null){
queue.add(node.right);
}
len--;
}
result.add(itemList);
}
return result;
}
可以发现,只需要在每次节点出队的时候,进行一个判断是否有左叶子节点就好了
代码如下:
//3、层序遍历
//需要借助一个队列来完成
public int sumOfLeftLeaves2(TreeNode root){
if (root == null) return 0;
int sum = 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
TreeNode node = queue.poll();
if (node.left != null && node.left.left == null && node.left.right == null){
sum += node.left.val;
}
if (node.left != null){
queue.add(node.left);
}
if (node.right != null){
queue.add(node.right);
}
}
return sum;
}