目录
难度:简单
今天刷翻转二叉树,大家有兴趣可以点上面链接,看看题目要求,试着做一下。
给你一棵二叉树的根节点?root
?,翻转这棵二叉树,并返回其根节点。
可以先简单看一下解题思路,然后照着代码看思路,会更容易理解一些。
方法1递归
方法2利用栈/队列
实际上,递归相当于隐式栈/队列,方法2即为显式
二叉树镜像定义:
? ? ? ? 对于二叉树中任意节点 root,设其左 / 右子节点分别为 left,right ;
? ? ? ? 则在二叉树的镜像中的对应 root 节点,其左 / 右子节点分别为 right,left 。
解题思路(递归):
我们从根节点开始,递归地对树进行遍历,并从叶子节点先开始翻转。
如果当前遍历到的节点 root的左右两棵子树都已经翻转,那么我们只需要交换两棵子树的位置,即可完成以 root 为根节点的整棵子树的翻转。
1、终止条件:当节点root为空(即越过叶子节点时),返回null
2、递归: ??
? ? ? ? ? ? ?初始化临时节点tmp,用于临时存储root的左子节点。
? ? ? ? ? ? ? 递归右子节点,并将返回值作为root的左子节点
? ? ? ? ? ? ?递归左子节点,并将返回值作为root的右子节点
3、最后返回当前节点root
可结合题解PDF进行理解--->226. 翻转二叉树 - 力扣(LeetCode)?
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;//当节点root为空(即越过叶子节点时),返回null
TreeNode tmp = root.left; //初始化临时节点tmp,用于临时存储root的左子节点。
root.left = invertTree(root.right);//递归右子节点,并将返回值作为root的左子节点
root.right = invertTree(tmp);//递归左子节点,并将返回值作为root的右子节点
return root;//最后返回当前节点root
}
}
1、由代码可知递归先遍历完整棵树的右子树遍历左左子树
2、为何序暂存root的左子节点?
? ? ??在递归右子节点执行完后,root.left的值已发生改变,此时直接递归左子节点则会出问题
?
利用栈(或队列)遍历树的所有节点node,并交换每个 node 的左 / 右子节点。
? 1、 特殊处理:当root为空时,直接返回null
? ?2、初始化:创建栈/队列,加入根节点
? ?3、循环交换(当stack为空时跳出循环)
? ? ? ? 出栈:弹出节点赋值给节点node
? ? ? ? ?添加子节点:将node节点的左右子节点压入栈
? ? ? ? 交换:利用临时节点tmp,对node的左右子节点进行交换
4、最后返回根节点root
代码实现(利用栈/队列):
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;//当root为空时,直接返回null
Stack<TreeNode> stack = new Stack<>() {{ add(root); }};//创建栈/队列,加入根节点
while (!stack.isEmpty()) {//循环交换(当stack为空时跳出循环)
TreeNode node = stack.pop(); //弹出节点赋值给节点node
if (node.left != null) stack.add(node.left);//将node节点的左右子节点压入栈
if (node.right != null) stack.add(node.right);//将node节点的左右子节点压入栈
TreeNode tmp = node.left;
node.left = node.right;//利用临时节点tmp,对node的左右子节点进行交换
node.right = tmp;
}
return root;//返回根节点root
}
}