Java算法 二叉树的中序遍历、二叉树的最大深度

小王的Java刷题日记Day7

记录刷题过程,作为笔记和分享,坚持每天刷题,每天进步,编程语言为Java。

题目一:二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历

例如:输入:root = [1,null,2,3]

输出:[1,3,2]

思路一:递归  (简单)  时间复杂度O(n)

1、按照访问左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样的方式遍历,直到遍历完整棵树。

2、递归实现

/**  二叉树的定义
 * Definition for a binary tree node.
 * public 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;
 *     }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer>res=new ArrayList<Integer>();
        dfs(res,root);
        return res;
    }
    void dfs(List<Integer>res,TreeNode root){
        if(root==null){    // 当前节点为空,直接返回
            return;
        }
        dfs(res,root.left);  // 递归遍历左子树
        res.add(root.val);    // 将当前节点的值添加到结果列表
        dfs(res,root.right);   // 递归遍历右子树
    }
}

思路二:迭代法 (较难)  时间复杂度O(n)

1、递归实现时,是函数自己调用自己,一层层的嵌套下去,操作系统/虚拟机自动帮我们用 来保存了每个调用的函数,现在我们需要自己模拟这样的调用过程。

2、递归的调用过程是不断往左边走,当左边走不下去了,就打印节点,并转向右边,然后右边继续这个过程。我们在迭代实现时,就可以用栈来模拟上面的调用过程。
 

/**  二叉树的定义
 * Definition for a binary tree node.
 * public 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;
 *     }
 * }
 */
class Solution {

    public List<Integer> inorderTraversal(TreeNode root) {

        List<Integer> res = new ArrayList<Integer>();

        Stack<TreeNode> stack = new Stack<TreeNode>();

        while (stack.size() > 0 || root != null) {

            // 不断往左子树方向走,每走一次就将当前节点保存到栈中
            // 这是模拟递归的调用

            if (root != null) {
                stack.add(root); // 将当前节点保存到栈中
                root = root.left; // 继续往左子树方向走
            } else {

                // 当前节点为空,说明左边走到头了,从栈中弹出节点并保存
                // 然后转向右边节点,继续上面整个过程

                TreeNode tmp = stack.pop(); // 从栈中弹出节点
                res.add(tmp.val); // 将弹出节点的值保存到结果列表中
                root = tmp.right; // 转向右边节点
            }

        }

        return res;

    }

}

题目二:二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

例如:输入:root = [3,9,20,null,null,15,7]

输出:3

思路一:后续遍历    时间复杂度O(n) 

关键点: 此树的深度和其左(右)子树的深度之间的关系。显然,此树的深度 等于 左子树的深度 与 右子树的深度中的 最大值 +1 。

终止条件: 当 root​ 为空,说明已越过叶节点,因此返回 深度 000 。
递推工作: 本质上是对树做后序遍历。

1、计算节点 root​ 的 左子树的深度 ,即调用 maxDepth(root.left)。

2、计算节点 root​ 的 右子树的深度 ,即调用 maxDepth(root.right)。

返回值: 返回 此树的深度 ,即 max(maxDepth(root.left), maxDepth(root.right)) + 1。

/**  定义二叉树
 * Definition for a binary tree node.
 * public 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;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        } else {
            int leftHeight = maxDepth(root.left);
            int rightHeight = maxDepth(root.right);
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }
}

思路二:层序遍历  时间复杂度O(n)

关键点: 每遍历一层,则计数器 +1 ,直到遍历完成,则可得到树的深度。

初始化: 队列 queue (加入根节点 root ),计数器 res = 0。
循环遍历: 当 queue 为空时跳出。

1、初始化一个空列表 tmp ,用于临时存储下一层节点。
2、遍历队列: 遍历 queue 中的各节点 node ,并将其左子节点和右子节点加入 tmp。
3、更新队列: 执行 queue = tmp ,将下一层节点赋值给 queue。
4、统计层数: 执行 res += 1 ,代表层数加 111。

返回值: 返回 res 即可。

/**  二叉树的定义
 * Definition for a binary tree node.
 * public 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;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        List<TreeNode> queue = new LinkedList<>() {{ add(root); }}, tmp;
        int res = 0;
        while (!queue.isEmpty()) {
            tmp = new LinkedList<>();
            for(TreeNode node : queue) {
                if (node.left != null) tmp.add(node.left);
                if (node.right != null) tmp.add(node.right);
            }
            queue = tmp;
            res++;
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值