【算法系列之二叉树I】leetcode226.翻转二叉树

非递归实现前序遍历

力扣题目链接

解决思路

  1. 前序遍历,中左右。
  2. 先放右节点,后放左节点。

Java实现

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        //中左右
        Stack<TreeNode> stack = new Stack<>();
       
        List<Integer> res = new ArrayList<>();
        if(root==null){
            return res;
        }
         stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
            res.add(node.val);
        }
        return res;
    }
}

非递归实现中序遍历

力扣题目链接

解决思路

  1. 左中右
  2. 使用指针记录当前遍历的节点,挨个将左节点放入栈中。
  3. 不断从栈中弹出节点,栈里面的元素是左中。将右节点压入栈中。

Java实现

class Solution_LC94 {
    public List<Integer> inorderTraversal(TreeNode root) {
        //左中右
        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {

                stack.push(cur);
                cur = cur.left;
            } else {
                cur = stack.pop();
                res.add(cur.val);
                cur = cur.right;
            }
        }
        return res;
    }

    public static void main(String[] args) {
        //[1,null,2,3]
        List<Integer> res = new Solution_LC94().inorderTraversal(new TreeNode(1, null, new TreeNode(2, new TreeNode(3), null)));
        System.out.println(res);
    }
}

非递归实现后续遍历

力扣题目链接

解决思路

  1. 先序遍历是中左右,后续遍历是左右中

Java实现

class Solution_LC145 {

    public List<Integer> postorderTraversal(TreeNode root) {
        //后序遍历  左右中     反过来   中右左
        Stack<TreeNode> stack = new Stack<>();

        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (node.left != null) {
                stack.push(node.left);
            }
            if (node.right != null) {
                stack.push(node.right);
            }
            res.add(node.val);
        }
        Collections.reverse(res);
        return res;
    }

    public static void main(String[] args) {
        List<Integer> res = new Solution_LC145().postorderTraversal(new TreeNode(1, null, new TreeNode(2, new TreeNode(3), null)));
        System.out.println(res);
    }

}

226.翻转二叉树

力扣题目链接

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

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

解决思路

  1. 可以使用前序遍历,不能使用中序遍历
  2. 先换左节点,再换右节点,最后左右节点。

Java实现

class Solution_LC226 {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        swap(root);
        return root;
    }

    private void swap(TreeNode root) {
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
    }
}

101. 对称二叉树

力扣题目链接

给你一个二叉树的根节点 root , 检查它是否轴对称。

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

解决思路

  1. 左右节点比较。左节点为空,右节点不为空,直接返回false。
  2. 比较的左孩子的左节点和右孩子的右节点。

Java实现

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return compare(root.left, root.right);
    }

    private boolean compare(TreeNode left, TreeNode right) {
        if (left == null && right != null) {
            return false;
        }
        if (left != null && right == null) {
            return false;
        }
        if (left == null && right == null) {
            return true;
        }
        if (left.val != right.val) {
            return false;
        }
        return compare(left.left, right.right) && compare(left.right, right.left);
    }

    public static void main(String[] args) {
        boolean res = new Solution().isSymmetric(new TreeNode(1, new TreeNode(2, new TreeNode(3), new TreeNode(4)), new TreeNode(2, new TreeNode(4), new TreeNode(3))));
        System.out.println(res);
    }
}

104.二叉树的最大深度

力扣题目链接

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 `[3,9,20,null,null,15,7]`,
返回它的最大深度 3 。

解决思路

  1. 终止条件,如果root为空,高度为0
  2. 递推逻辑,比较左右节点的高度,较大值+1。

Java实现

递归实现

class Solution_LC104 {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
    }
}

层序遍历

class Solution_LC101_II {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while (!queue.isEmpty()) {
            depth++;
            int len = queue.size();
            for (int i = 0; i < len; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return depth;
    }

    public static void main(String[] args) {
        TreeNode treeNode = new TreeNode(1, new TreeNode(2, new TreeNode(4), null), new TreeNode(3, null, new TreeNode(5)));
//        [1,2,3,4,null,null,5]
        int res = new Solution_LC101_II().maxDepth(treeNode);
        System.out.println(res);
    }
}

559.n叉树的最大深度

力扣题目链接

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

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

解决思路

  1. 思路同上。

Java实现

递归实现

class Solution_LC559 {
    public int maxDepth(Node root) {
        if (root == null) {
            return 0;
        }
        int depth = 0;
        for (int i = 0; i < root.children.size(); i++) {
            depth = Math.max(depth, maxDepth(root.children.get(i)));
        }
        return depth + 1;
    }
}

111.二叉树的最小深度

力扣题目链接

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

**说明:**叶子节点是指没有子节点的节点。

解决思路

  1. 最近叶子节点。
  2. 如果左节点为空,获取右子树+1;如果右节点为空,获取左子树的高度+1。空节点不在计算范围内。

Java实现

class Solution_LC111 {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null) {
            return minDepth(root.right) + 1;
        }
        if (root.right == null) {
            return minDepth(root.left) + 1;
        }
        return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
    }
}

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

力扣题目链接

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

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

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

解决思路

  1. 递归实现

Java实现

class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int count = 1;
        if (root.left != null) {
            count += countNodes(root.left);
        }
        if (root.right != null) {
            count += countNodes(root.right);
        }
        return count;
    }
}

110.平衡二叉树

力扣题目链接

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

输入:root = [3,9,20,null,null,15,7]
输出:true

解决思路

  1. 获取当前节点的左子树的高度
  2. 判断左右高度是否小于等于1,且左子树是否平衡,右子树是否平衡。

Java实现

class Solution_LC110 {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        return Math.abs(getDepth(root.left) - getDepth(root.right)) <= 1 && isBalanced(root.right) && isBalanced(root.left);
    }

    private Integer getDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return Math.max(getDepth(root.left), getDepth(root.right)) + 1;
    }
}

【算法系列之二叉树I】leetcode226.翻转二叉树_第1张图片

你可能感兴趣的:(算法,算法,leetcode,数据结构)