【LeetCode刷题笔记】(九)树(1)二叉树

107 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情 这也是第42篇文章

前言

在上两篇文章讲搜索算法时,也提到过搜索在图和树中的应用。所以这篇文章再来谈谈树这个数据结构。

但是树太多了,这篇文章中我们先以二叉树作为研究对象,谈谈它的构造过程和一些经典问题。

递归构造树的三种方式

树可以分为三大部分:根节点,左子树,右子树。遍历的顺序形成了三种不同的构造方式。

前序遍历(preoder)

指的是先访问根节点,再分别访问左右子树。这种算法和深度优先搜索有点像。

注意事项:递归结束条件(后续不再提醒)

class Solution {
    List<Integer> list=new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        preorder(root);
        return list;
    }

    public void preorder(TreeNode root){
        if(root==null) return ;
        list.add(root.val);
        preorder(root.left);
        preorder(root.right);
    }
}

中序遍历

和前序遍历类似,只需要把list.add(root.val);夹到两段递归代码中间,然后把递归函数preorder的名字也改一下就行了。

class Solution {
    List<Integer> list=new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        inorder(root);
        return list;
    }

    public void inorder(TreeNode root){
        if(root==null) return ;
        inorder(root.left);
        list.add(root.val);
        inorder(root.right);
    }
}

后序遍历

相信大家都已经懂套路了,我就只放最关键的代码了:

postorder(root.left); 
postorder(root.right);
list.add(root.val); 

二叉树最大深度

思路

这个问题也可以通过递归遍历左右子树解决。而所谓“最大”,可理解为选取左子树和右子树中深度较大者。

代码实现

class Solution {
    public int maxDepth(TreeNode root) {
        return dfs(root,0);
    }

    public int dfs(TreeNode root,int depth){
        if(root==null) return depth;
        depth++;
        int left=dfs(root.left,depth);
        int right=dfs(root.right,depth);
        return Math.max(left,right);
    }
}

求根节点到叶节点数字之和

是“计算叶子结点个数”一题的升级版。

思路

也是递归遍历左右子树,会用到前缀和的思想,也就是:

int pre=val*10+root.val;

来达到题目要求的“数字的和”的要求。

代码实现

class Solution {
    public int sumNumbers(TreeNode root) {
        return dfs(root,0);
    }

    public int dfs(TreeNode root,int val){
        if(root==null) return 0;
        int pre=val*10+root.val;
        if(root.left==null&&root.right==null) return pre;
        return dfs(root.left,pre)+dfs(root.right,pre);
    }
}