找树左下角的值[(前序遍历 || 分层遍历)变体]

前言

二叉树遍历有递归遍历和层次遍历,这是操作二叉树的基础。

一、找树左下角的值

在这里插入图片描述

二、遍历+改进

1、前序遍历

// 找树左下角的值。
public class FindBottomLeftValue {
    /*
    target:找出二叉树最下最左边的值。
    该值特点:深度最大。
    如何拿到深度最大的节点值?通过遍历,在遍历的过程中传入深度变量,用一个变量记录最大深度那个节点值。
    当同深度有多个值时,如何拿到最左边那个值?可通过前序遍历的方式去寻找更深的节点,当深度一样时,还是保持第一次记录的节点值。
     */
    public int findBottomLeftValue(TreeNode root) {
        // 记录当前遍历过程中最左最深的节点值。
        // 初始化为根节点值,深度为1.
        int[] rs = new int[]{root.val, 1};
        // 前序遍历寻找更深的节点值。
        preOrder(root, 1, rs);
        // 返回最深最左的节点值。
        return rs[0];
    }

    /**
     * @param root  树根节点。
     * @param level 当前所在树的深度。
     * @param rs    存储最左最深的节点值和深度。
     */
    private void preOrder(TreeNode root, int level, int[] rs) {
        if (null == root) return;
        // 在前序遍历的基础上对最深最左节点进行更新。
        if (rs[1] < level) {
            rs[0] = root.val;
            // 根据前序遍历特点,能比当前记录的还深的节点,一定在下一层。
            ++rs[1];
        }
        // 先左后右。
        preOrder(root.left, level + 1, rs);
        preOrder(root.right, level + 1, rs);
    }

    // Definition for a binary tree node.
    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
}

2、层次遍历

// 练习一下层次遍历。
class FindBottomLeftValue2 {
    /*
    target:找出二叉树最下最左边的值。
    该值特点:深度最大。
    如何拿到深度最大的节点值?通过遍历,在遍历的过程中传入深度变量,用一个变量记录最大深度那个节点值。
    当同深度有多个值时,如何拿到最左边那个值?可通过层次遍历拿最后一层的第一个节点的值即可。
    如何拿最后一层的第一个节点的值?可每次记录当前层的头节点的值。
    如何分层?通过每层有多少节点数,访问一个就减一来判是否马上开启新一层的遍历。
     */
    public int findBottomLeftValue(TreeNode root) {
        // 层次遍历,按队列的出入方式来进行。
        Queue<TreeNode> que = new LinkedList<>();
        // 初始化第一层节点。
        que.add(root);
        // 记录当前层的节点个数,当前层为第一层,只有root节点。
        int curSize = 1;
        // 记录第一层的第一个节点的值。该节点为root。
        int leftNodeVal = root.val;
        // 以循环的方式开启层次遍历。
        while (!que.isEmpty()) {
            // 从左到右遍历当前层节点。
            TreeNode node = que.poll();
            // 将左右非空孩子加入层次遍历的路径中。
            if (null != node.left) que.add(node.left);
            if (null != node.right) que.add(node.right);
            // 更新当前层还剩余未遍历的节点数,并根据情况完成下一层节点数的更新和最左节点值的更新。
            if (--curSize == 0) {
                curSize = que.size();
                // 由于循环所需,que此时可能已经为空,更下一层就没有了。
                if (!que.isEmpty()) leftNodeVal = que.peek().val;
            }
        }
        // 返回最深一层的第一个节点值。
        return leftNodeVal;
    }

    // Definition for a binary tree node.
    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
}

总结

1)经典前序遍历+分层遍历。

参考文献

[1] LeetCode 找树左下角的值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值