【LeetCode】404. 左叶子之和

1.问题

给定二叉树的根节点 root ,返回所有左叶子之和。

示例 1

在这里插入图片描述

输入: root = [3,9,20,null,null,15,7]
输出: 24

解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

示例 2

输入: root = [1]
输出: 0

提示:

  • 节点数在 [1, 1000] 范围内
  • -1000 <= Node.val <= 1000

2.解题思路

2.1 递归

按照题目描述,我们需要遍历每个树节点,对于目标值,我们需要判定某个节点是否是需要的,既要判定是叶子节点,又要判定是左边的叶子节点,因而对于和的组成,进行分类谈论,如下:
1)节点为null,返回;
2)该节点左子树不为空,且为叶子节点,sum+=该节点的value;否则递归左子树;
3)该节点右子树不为空,这里又要分类:
3.1)右子树为叶子节点,不是题目需要的值的组成部分;
3.2)右子树的子节点,只要左右其中一个不为空,继续递归。

伪代码:

//sumOfLeftLeaves(TreeNode root)为计算root所有左叶子节点的和的函数。
int sumOfLeftLeaves(TreeNode root){
	//节点为null
	if root 为null
		return 0;
	//左子树
	if root.left 不为null
		//root.left为叶子节点
		if(root.left为叶子节点){
			sum+=root.left.val;
		}
		//否则,继续递归左子树
		else {
			sum+=sumOfLeftLeaves(root.left);
		}
	
	//右子树
	if root.right 不为null
		//只要不是叶子节点,继续递归
		if root.right 不是叶子节点
		 sum+=sumOfLeftLeaves(root.right);
	return sum;
}

而判定是否是叶子节点,代码如下:

//判定是叶子节点
private boolean isLeaf(TreeNode node){
    return null!=node && null==node.left && null==node.right;
}

2.2 改进的递归

上述递归流程,过程是清晰明了的,但判定逻辑有点复杂,对于题目已知的条件,我们只需要抓重点,左叶子节点的和,其他都放在递归算法里了。
详细代码,见第3节代码。

2.3 BFS

前面讨论的算法,遍历路径类似前序遍历,先根节点,再左右子节点,本质思想还是深度优先(DFS)。在二叉树遍历系列文章中,我们可以利用层序遍历,同样可以解决本章问题,其思想还是广度优先算法(BFS)。

3.代码

3.1 递归算法

public int sumOfLeftLeaves2(TreeNode root) {
   if(null==root){
       return 0;
   }
   int sum=0;
   if(null!=root.left){
       //左子树为叶子节点,直接加上,否则继续递归左子树
       if(isLeaf(root.left)){
           sum+=root.left.val;
       }else {
           sum+=sumOfLeftLeaves(root.left);
       }
   }
   //右子树只要不为空,且至少存在一个节点(不管是左还是右)
   if(null!=root.right){
       if(!isLeaf(root.right)){
           sum+=sumOfLeftLeaves(root.right);
       }
   }
   return sum;
}

3.2 改进的递归

int sum=0;
public int sumOfLeftLeaves(TreeNode root) {
    dfs(root);
    return sum;
}

private void dfs(TreeNode root){
    if(null==root){
        return;
    }
    //是左叶子节点
    if(null!=root.left && isLeaf(root.left)){
        sum+=root.left.val;
    }
    //继续遍历左右子树
    dfs(root.left);
    dfs(root.right);
}

3.3 广度优先算法

public int sumOfLeftLeaves(TreeNode root) {
   if(null==root){
       return 0;
   }
   int sum=0;
   //队列
   Queue<TreeNode> q=new LinkedList<>();
   q.offer(root);
   TreeNode node;
   //遍历队列
   while(!q.isEmpty()){
       node=q.poll();
       if(null==node){
           continue;
       }
       //左叶子节点
       if(null!=node.left && isLeaf(node.left)){
           sum+=node.left.val;
       }
       q.offer(node.left);
       q.offer(node.right);
   }
   return sum;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值