随想录笔记-二叉树练习题

翻转二叉树

交换左右指针

226. 翻转二叉树 - 力扣(LeetCode)

java 复制代码
//DFS递归
class Solution {
   /**
     * 前后序遍历都可以
     * 中序不行,因为先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子),再右孩子交换孩子(此时其实是对原来的左孩子做交换)
     */
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        swapChildren(root);
        return root;
    }

    private void swapChildren(TreeNode root) {
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
    }
}
java 复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
   if(root==null) return null;
   TreeNode temp=root.left;
   root.left=invertTree(root.right);
   root.right=invertTree(temp);
   return root;
    }
}
java 复制代码
//BFS
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {return null;}
        ArrayDeque<TreeNode> deque = new ArrayDeque<>();
        deque.offer(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            while (size-- > 0) {
                TreeNode node = deque.poll();
                swap(node);
                if (node.left != null) deque.offer(node.left);
                if (node.right != null) deque.offer(node.right);
            }
        }
        return root;
    }

    public void swap(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

N叉树的前序遍历

java 复制代码
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    public List<Integer> preorder(Node root) {
        List<Integer> res=new ArrayList<>();
        if(root==null){
            return res;
        }
       preorderorder(root,res);
       return res;
    }
    public void preorderorder(Node root,List<Integer> res){
        res.add(root.val);
        for(Node child:root.children){
            preorderorder(child,res);
        }
    }

N叉树的后序遍历

java 复制代码
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
}
*/

class Solution {
    public List<Integer> postorder(Node root) {
        List<Integer> res=new ArrayList<>();
        if(root==null){
            return res;
        }
       postorderorder(root,res);
       return res;
    }
    public void postorderorder(Node root,List<Integer> res){
        
       for(Node child:root.children){
            postorderorder(child,res);
        }
        res.add(root.val); 
    }
}

对称二叉树

101. 对称二叉树 - 力扣(LeetCode)

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
   if(root==null) return true;
    return compare(root.left,root.right);
    
    }
    public boolean compare(TreeNode left,TreeNode right){
        if(left==null&&right==null)
        return true;
        if(left==null&&right!=null)
        return false;
        if(left!=null&&right==null)
        return false;
        if(left.val!=right.val)
        return false;

        boolean compare_innner=compare(left.left,right.right);
        boolean compare_outside=compare(left.right,right.left);
        return compare_innner&&compare_outside;

    }
}

变型题目

相同的树

java 复制代码
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
    if(p==null&&q==null)
    return true;
    if(p==null&&q!=null)
    return false;
    if(p!=null&&q==null)
    return false;
    if(p.val!=q.val)
    return false;

    boolean inner=isSameTree(p.left,q.left);
    boolean outside=isSameTree(p.right,q.right);
    return inner&&outside;
    }

}

变形题目二:

另一棵数的子树

两个树相同是里面一种特殊的情况

运用迭代的思路

java 复制代码
class Solution {
    public boolean isSubtree(TreeNode p, TreeNode q) {
     if(q==null) return true;
     if(p==null) return false;
     return isSubtree(p.left,q)||isSubtree(p.right,q)||isSameTree(p,q);

    }
    
    public boolean isSameTree(TreeNode p, TreeNode q) {
    if(p==null&&q==null)
    return true;
    if(p==null&&q!=null)
    return false;
    if(p!=null&&q==null)
    return false;
    if(p.val!=q.val)
    return false;

    boolean inner=isSameTree(p.left,q.left);
    boolean outside=isSameTree(p.right,q.right);
    return inner&&outside;
    }


}

二叉树的最大深度

利用层序遍历的思路

java 复制代码
class Solution {
    public int maxDepth(TreeNode root) {
    int res=0;
    if(root==null) return res;

Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
    int len=queue.size();
   
    while(len>0){
        TreeNode node=queue.poll();
        
        len--;
        if(node.left!=null) queue.offer(node.left);
        if(node.right!=null) queue.offer(node.right);
    }
    res++;
  
}
return res;
    }
}

官方题解:这个太巧妙了,我感觉我记不住

尝试去理解官方说的前序的思路

代码随想录 (programmercarl.com)

java 复制代码
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);
        return Math.max(leftDepth, rightDepth) + 1;

N叉树的最大深度

利用层序遍历的思路

java 复制代码
class Solution {
    public int maxDepth(Node root) {
        int res=0;
        if(root==null) return res;
        Queue<Node> queue=new LinkedList<Node>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int len=queue.size();
            while(len>0){
                Node node=queue.poll();
                len--;

                for(Node n:node.children){
                    if(n!=null){
                        queue.offer(n);
                    }
                }
                
            }
            res++;
        }
return res;
    }
}

官方题解:

java 复制代码
class Solution {
    /*递归法,后序遍历求root节点的高度*/
    public int maxDepth(Node root) {
        if (root == null) return 0;

        int depth = 0;
        if (root.children != null){
            for (Node child : root.children){
                depth = Math.max(depth, maxDepth(child));
            }
        }

        return depth + 1; //中节点
    }  
}

二叉树的最小深度

java 复制代码
class Solution {
    public int minDepth(TreeNode root) {
    int res=0;
    if(root==null) return res;

Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
    int len=queue.size();
    res++;
    while(len>0){
    TreeNode   node=queue.poll();
        
        len--;
        if(node.left!=null) queue.offer(node.left);
        if(node.right!=null) queue.offer(node.right);
        if(node.left==null&&node.right==null)return res;
  
    }
   
    
}
return res;
    }
}

完美二叉树的节点个数

java 复制代码
class Solution {
    public int countNodes(TreeNode root) {
        int res=0;
    if(root==null) return res;

Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
    int len=queue.size();
   
    while(len>0){
        TreeNode node=queue.poll();
        res++;
        len--;
        if(node.left!=null) queue.offer(node.left);
        if(node.right!=null) queue.offer(node.right);
    }
    
  
}
return res;

    }
}

平衡二叉树

这里强调一波概念:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。

一个是从上到下,一个是从下到上

遍历方式不同,一个是中左右,一个是左右中

java 复制代码
class Solution {
    public boolean isBalanced(TreeNode root) {
     return getheight(root)!=-1;
    }
    public int getheight(TreeNode root){
        if(root==null){
            return 0;
        }
        int left=getheight(root.left);
        if(left==-1){
            return -1;
        }

        int right=getheight(root.right);
        if(right==-1){
            return -1;
        }

        if(Math.abs(left-right)>1){
            return -1;
        }

        return Math.max(left,right)+1;
    }
}

二叉树的所有路径

说这道题目利用回溯的思想,第二个代码传入

deal(root.right,temp); 相当于回去了

deal(root.left,temp);

deal(root.right,temp);
本周小结!(二叉树系列二) | 代码随想录 (programmercarl.com)

就是遍历二叉树的所有路径,遇到遍历,一般的思路就是迭代和递归

这里用迭代的思想,递归的思想我脑子是真的转不过来

迭代三要素:

确定参数:传入参数和返回参数

终止条件:

处理逻辑:

如果处理逻辑比较麻烦,可以单独写一个函数抽离出来,不一定非得自己反复调用自己

java 复制代码
class Solution {
     List<String> res=new ArrayList<>();


    public List<String> binaryTreePaths(TreeNode root) {
    deal(root,"");
     return res;

    }

public void deal(TreeNode root,String s){
     if(root==null) {
        return ;
     }
     
    if(root.left==null&&root.right==null){
    res.add(new StringBuilder(s).append(root.val).toString());
    return ;
     }

    String temp=new StringBuilder(s).append(root.val).append("->").toString();
    deal(root.left,temp);
    deal(root.right,temp);
    
}



}

讲了这么多二叉树题目的迭代法,有的同学会疑惑,迭代法中究竟什么时候用队列,什么时候用栈?

如果是模拟前中后序遍历就用栈,如果是适合层序遍历就用队列,当然还是其他情况,那么就是 先用队列试试行不行,不行就用栈。

左叶子之和

首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。

java 复制代码
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {

if(root==null)
return 0;

int left=sumOfLeftLeaves(root.left);
int right=sumOfLeftLeaves(root.right);

int mid=0;
if(root.left!=null&&root.left.left==null&&root.left.right==null){
    mid=root.left.val;
}
return mid+left+right;

    }
}
相关推荐
CoovallyAIHub13 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
Java中文社群13 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心13 小时前
从零开始学Flink:数据源
java·大数据·后端·flink
间彧13 小时前
Spring Boot项目中如何自定义线程池
java
间彧14 小时前
Java线程池详解与实战指南
java
用户2986985301414 小时前
Java 使用 Spire.PDF 将PDF文档转换为Word格式
java·后端
NAGNIP14 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo14 小时前
半开区间和开区间的两个二分模版
算法
渣哥14 小时前
ConcurrentHashMap 1.7 vs 1.8:分段锁到 CAS+红黑树的演进与性能差异
java
moonlifesudo14 小时前
300:最长递增子序列
算法