二叉树:二叉树的反转,一道简单有经典的题目
226. 翻转二叉树
听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最后被Google拒绝了。
遍历的过程中去翻转每一个节点的左右孩子就可以达到整体翻转的效果。
「注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果」
「这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不行,因为中序遍历会把某些节点的左右孩子翻转了两次!建议拿纸画一画,就理解了」
递归法
递归三部曲:
1.确定递归函数的参数和返回值
参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。
返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*
2.确定终止条件
当前节点为空的时候,就返回
3.确定单层递归的逻辑
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL)
return root;
swap(root->right, root->left);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
迭代法
递归能做,栈也能做中给出了前中后序迭代方式的写法,所以本地可以很轻松的切出如下迭代法的代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> stack;
if(root == NULL)
return root;
TreeNode* cur;
stack.push(root);
while(!stack.empty())
{
cur = stack.top();
stack.pop();
swap(cur->left, cur->right);
if(cur->right != NULL)
{
stack.push(cur->right);
}
if(cur->left != NULL)
{
stack.push(cur->left);
}
}
return root;
}
};
总结
「二叉树解题的大忌就是自己稀里糊涂的过了(因为这道题相对简单),但是也不知道自己是怎么遍历的。」