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

翻转二叉树

交换左右指针

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;

    }
}
相关推荐
抚月code1 分钟前
Java线程池
java
IT枫斗者6 分钟前
集合工具类
java·linux·数据库·windows·算法·microsoft
星迹日6 分钟前
C语言:结构体
c语言·开发语言·经验分享·笔记
朱皮皮呀12 分钟前
排序算法-归并排序
数据结构·算法·排序算法·归并排序
MogulNemenis14 分钟前
力扣100题——贪心算法
算法·leetcode·贪心算法
aWty_15 分钟前
机器学习--线性回归
python·算法·机器学习·线性回归
会敲代码的小张19 分钟前
设计模式-观察者模式
java·开发语言·后端·观察者模式·设计模式·代理模式
jyan_敬言22 分钟前
虚拟机centos_7 配置教程(镜像源、配置centos、静态ip地址、Finalshell远程操控使用)
linux·运维·服务器·c语言·数据结构·tcp/ip·centos
UrSpecial25 分钟前
【数据结构取经之路】图解AVL树
数据结构
QXH20000026 分钟前
数据结构—顺序表
数据结构