一、分析
理解递归思想的条件下很容易想到解题思路,当然可能有人会有疑问,那什么情况下知道使用递归呢,有个最简单的办法如果算法里需要重复循环用同一个思路执行得到结果,那么必然可以使用递归。进行翻转本质上可以拆分为两步递归,递归翻转左子树和递归翻转右子树分。无论是否使用递归本质思想是一致的,使用非递归的方式则需要借助使用栈或者队列的结构进行存储未交换的子节点。
二、反转二叉树的实现方式
方式一:使用栈实现
本质思想是,左右节点进行交换,循环翻转每个节点的左右子节点,将未翻转的子节点存入栈中,循环直到栈里所有节点都循环交换完为止。
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()) {
final TreeNode node = stack.pop();
final TreeNode left = node.left;
node.left = node.right;
node.right = left;
if(node.left != null) {
stack.push(node.left);
}
if(node.right != null) {
stack.push(node.right);
}
}
return root;
}
方式二:使用队列实现
本质思想是,左右节点进行交换,循环翻转每个节点的左右子节点,将未翻转的子节点存入队列中,循环直到栈里所有节点都循环交换完为止。
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
TreeNode left = node.left;
node.left = node.right;
node.right = left;
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
return root;
}
方式三:使用递归来实现
本质思想,是左右节点进行交换,交换前递归调用对根结点的左右节点分别进行处理,保证交换前左右节点已经翻转。
public TreeNode invertTree(TreeNode node) {
if (node == null) {
return null;
}
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
invertTree(node.left);
invertTree(node.right);
return node;
}