力扣刷题--左叶子之和 404题

方法思路

本题的难点在于确定什么是左叶子
左叶子就是有左孩子节点,并且这个左孩子节点没有左右孩子
然后利用后序遍历、递归法还是层序遍历做都可以

方法一:后序遍历之递归法

首先写出二叉树的后序遍历(递归法):

	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;
    }
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值