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

翻转二叉树

交换左右指针

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;

    }
}
相关推荐
飞舞花下15 分钟前
MAVEN私有仓库配置-Nexus私有仓库
xml·java·maven
毕设源码-赖学姐19 分钟前
【开题答辩全过程】以 基于SpringBoot的健身房管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
小桥流水---人工智能21 分钟前
风电机组故障诊断与状态监测方法的研究局限性整理(背景笔记)
笔记
仙俊红24 分钟前
LeetCode322零钱兑换
算法
颖风船26 分钟前
锂电池SOC估计的一种算法(改进无迹卡尔曼滤波)
python·算法·信号处理
551只玄猫40 分钟前
KNN算法基础 机器学习基础1 python人工智能
人工智能·python·算法·机器学习·机器学习算法·knn·knn算法
charliejohn41 分钟前
计算机考研 408 数据结构 哈夫曼
数据结构·考研·算法
POLITE31 小时前
Leetcode 41.缺失的第一个正数 JavaScript (Day 7)
javascript·算法·leetcode
Filotimo_1 小时前
EntityGraph的概念
java·开发语言·数据库·oracle