leetcode 算法-二叉树java总结——正在更新

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 二叉树遍历
    • 1、leetcode [144. 二叉树的前序遍历](https://leetcode.cn/problems/binary-tree-preorder-traversal/)
      • 递归法 O(n)
      • 迭代法O(n)
    • 2、 145. 二叉树的后序遍历
    • 3、leetcode 94. [二叉树的中序遍历-java版本](https://blog.csdn.net/qq_41810415/article/details/127433959?spm=1001.2014.3001.5502)
  • 二叉树的层序遍历
    • 4、leetcode 102. [二叉树的层序遍历-java实现](https://blog.csdn.net/qq_41810415/article/details/127479039?spm=1001.2014.3001.5502)
    • 5、[107. 二叉树的层序遍历 II-java实现](https://blog.csdn.net/qq_41810415/article/details/127487907?spm=1001.2014.3001.5502)
    • 6、[199. 二叉树的右视图](https://leetcode.cn/problems/binary-tree-right-side-view/)
    • 7、[637. 二叉树的层平均值](https://leetcode.cn/problems/average-of-levels-in-binary-tree/)
    • 8、[429. N 叉树的层序遍历](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/)
    • 9、[515. 在每个树行中找最大值](https://leetcode.cn/problems/find-largest-value-in-each-tree-row/)
    • 10、[leetcode 116. 填充每个节点的下一个右侧节点指针-java实现](https://blog.csdn.net/qq_41810415/article/details/127579305?spm=1001.2014.3001.5502)
    • 11、[117. 填充每个节点的下一个右侧节点指针 II](https://blog.csdn.net/qq_41810415/article/details/127579391?spm=1001.2014.3001.5502)
  • 二叉树的深度
    • 1、[leetcode 104. 二叉树的最大深度-java实现](https://blog.csdn.net/qq_41810415/article/details/127480375?spm=1001.2014.3001.5502)
    • 2、[leetcode 111. 二叉树的最小深度-java实现](https://blog.csdn.net/qq_41810415/article/details/127490150?spm=1001.2014.3001.5502)
  • [226. 翻转二叉树](https://leetcode.cn/problems/invert-binary-tree/)
  • [leetcode 101. 对称二叉树-java实现](https://blog.csdn.net/qq_41810415/article/details/127443333?spm=1001.2014.3001.5502)
  • [222. 完全二叉树的节点个数](https://leetcode.cn/problems/count-complete-tree-nodes/)
  • [leetcode 110. 平衡二叉树-java实现](https://blog.csdn.net/qq_41810415/article/details/127490060?spm=1001.2014.3001.5502)
  • [257. 二叉树的所有路径](https://leetcode.cn/problems/binary-tree-paths/)


前言

提前要了解二叉树的分类 二叉树的两种存储方式 二叉树的两大种遍历方式以及深度遍历中的三种遍历方式 常常与dfs bfs混合使用
本文只介绍二叉树相关的leetcode习题 对基础的语法知识点不做过多赘述


二叉树遍历

1、leetcode 144. 二叉树的前序遍历

递归法 O(n)

/**
 * 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 {
    List<Integer> ans = new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        dfs(root);
        return ans;
    }
    public void dfs(TreeNode root){
        if(root == null) return;
        ans.add(root.val);
         dfs(root.left);
        dfs(root.right);

    }
}

迭代法O(n)

class Solution {
    List<Integer> ans = new ArrayList<>();
    Stack<TreeNode> st = new Stack<>();
    public List<Integer> preorderTraversal(TreeNode root) {
         TreeNode cur = root;
         while(cur != null || !st.isEmpty()){
             while(cur != null){
                ans.add(cur.val);
                 st.push(cur);
                 cur = cur.left;
             }
             cur = st.pop();           
             cur = cur.right;
         }
        return ans;
    }
}

2、 145. 二叉树的后序遍历

先遍历根右左 然后翻转过来

class Solution {
     List<Integer> ans = new ArrayList<>();
     Stack<TreeNode> st = new Stack<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        TreeNode cur = root;
        while(cur != null || !st.isEmpty()){
            while(cur != null){
                ans.add(cur.val);
                st.push(cur);
                cur = cur.right;
            }
            cur = st.pop();
            cur = cur.left;           
        }
        Collections.reverse(ans);
        return ans;
    }
}

建立一个上一个节点

class Solution {
     List<Integer> ans = new ArrayList<>();
     Stack<TreeNode> st = new Stack<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        TreeNode cur = root;
        TreeNode pre = null;
        while(cur != null || !st.isEmpty()){
            while(cur != null){              
                st.push(cur);
                cur = cur.left;
            }
            cur = st.peek();
            //右边表示没遍历上一个节点
            if(cur.right != null && cur.right != pre){
                cur = cur.right;
            }else{
                st.pop();
                ans.add(cur.val);
                pre = cur;
                cur = null;   
            }
                    
        }
        
        return ans;
    }
}

3、leetcode 94. 二叉树的中序遍历-java版本

二叉树的层序遍历

4、leetcode 102. 二叉树的层序遍历-java实现

5、107. 二叉树的层序遍历 II-java实现

6、199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

leetcode 算法-二叉树java总结——正在更新_第1张图片

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

层序遍历的模板 在每一层中把该层中最后一个元素放入队列中即可

/**
 * 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> rightSideView(TreeNode root) {
         List<Integer> ans = new ArrayList<>();
        if(root == null) return ans;
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.add(root);
        while(!q.isEmpty()){
            int len = q.size();
            for(int i = 0 ; i < len ; i++){
                TreeNode t = q.poll();
                if(t.left != null)  q.add(t.left);
                if(t.right != null) q.add(t.right);
                if(i == len-1) ans.add(t.val);
            }
             
        }
        return ans;
 
    }
}

7、637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

leetcode 算法-二叉树java总结——正在更新_第2张图片

输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。

/**
 * 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<Double> averageOfLevels(TreeNode root) {
        List<Double> ans = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        if(root == null) return ans;
        q.add(root);
        while(!q.isEmpty()){
            int len = q.size();
            double sum = 0 ;
            for(int i = 0 ; i < len ; i ++){
                TreeNode t  = q.poll();
                sum += t.val;
                if(t.left != null) q.add(t.left);
                if(t.right != null) q.add(t.right);
            }
            ans.add(sum/len);
        }
        return ans;
    }
}

8、429. N 叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
leetcode 算法-二叉树java总结——正在更新_第3张图片

输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]

/*
// Definition for a Node.
class Node {
    public int val;
    public List children;

    public Node() {}

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

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

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> ans = new ArrayList<>();        
        Queue<Node> q = new LinkedList<>();
        if(root == null) return ans;
        q.add(root);
        while(!q.isEmpty()){
            List<Integer> res = new ArrayList<>();
            int len = q.size();
            for(int i = 0 ; i < len ; i ++){
                Node t = q.poll();
                res.add(t.val);
                 for(Node c : t.children) q.add(c);
            }
            ans.add(res);
        }
        return ans ;
    }
}

9、515. 在每个树行中找最大值

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
leetcode 算法-二叉树java总结——正在更新_第4张图片

输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]

/**
 * 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> largestValues(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        if(root == null) return ans;
        q.add(root);
        while(!q.isEmpty()){
            int len = q.size();
            int m = Integer.MIN_VALUE ;
            for(int i = 0 ; i < len ; i++){
                TreeNode t = q.poll();
                  m = Math.max(m,t.val);
                if(t.left != null) q.add(t.left);
                if(t.right != null) q.add(t.right);             
            }
             ans.add(m);
        }
        return ans;
    }
}

10、leetcode 116. 填充每个节点的下一个右侧节点指针-java实现

11、117. 填充每个节点的下一个右侧节点指针 II

二叉树的深度

1、leetcode 104. 二叉树的最大深度-java实现

2、leetcode 111. 二叉树的最小深度-java实现

226. 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
leetcode 算法-二叉树java总结——正在更新_第5张图片

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,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 TreeNode invertTree(TreeNode root) {
        if(root == null) return root;
        TreeNode t = root.left;
        root.left = root.right;
        root.right = t ;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

leetcode 101. 对称二叉树-java实现

222. 完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

leetcode 算法-二叉树java总结——正在更新_第6张图片

输入:root = [1,2,3,4,5,6]
输出:6

用二分的思想 O(log^2 n)

/**
 * 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 countNodes(TreeNode root) {
        if(root == null) return 0 ;
        int x = 1 , y = 1 ;
        TreeNode l = root.left ;
        TreeNode r = root.right ;
        while(l != null){//如果是root 的话 那么x y 初始化要是0
            l = l.left ;
            x++;
        } 
        while(r  != null){
            r = r.right;
            y++;
        } 
        //二者相同为满二叉树 2^x -1 
        if(x == y) return (1 << x) -1;
        //递归到左边算加上根节点 在递归到右边算
        return countNodes(root.left) + 1 + countNodes(root.right);
    }
}

leetcode 110. 平衡二叉树-java实现

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

leetcode 算法-二叉树java总结——正在更新_第7张图片

输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]

时间复杂度 O(n)
1、从根结点出发,递归走所有的路径,并把路径的值记录下来
2、递归过程中
若左子树和右子树都为null,则返回记录的路径s
若左子树不为null,则把左子树的值加入到路径中,递归到左子树
若右子树不为null,则把右子树的值加入到路径中,递归到右子树

/**
 * 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 {
    List<String> ans = new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
        if(root == null) return ans ;
        dfs(root,""+root.val);
        return ans;
    }
    public void dfs(TreeNode root,String s){
        if(root.left ==null && root.right ==null){
            ans.add(s);
            return ;
        }       
        if(root.left != null) dfs(root.left,s + "->"+root.left.val);
        if(root.right != null) dfs(root.right,s + "->"+root.right.val);
    }
}

你可能感兴趣的:(leetcode算法总结,leetcode,算法,java,leetcode算法总结)