> 文章列表 > 【算法系列之二叉树I】leetcode226.翻转二叉树

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

【算法系列之二叉树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.翻转二叉树