前言
继续二叉树其余操作:
记录 四十【226.翻转二叉树】
一、题目阅读
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
示例 2:
输入:root = [2,1,3]
输出:[2,3,1]
示例 3:
输入:root = []
输出:[]
提示:
树中节点数目范围在 [0, 100] 内
-100 <= Node.val <= 100
二、尝试实现
思路
如何翻转:每个节点的左右孩子交换。确定用递归实现。
(1)确定参数和返回值:
- 参数:根节点(整个树/某个子树)
- 返回值void。直接用指针修改对象。无需返回值。
(2)确定终止条件:
- 遇到叶子节点:没有左右孩子,可以return。
- 遇到空节点:直接return。
- if(!cur || cur->left == nullptr && cur->right == nullptr) return;
(3)逻辑:先深入到叶子节点,再交换操作。
- 先走左边:递归cur->left。
- 再走右边:递归cur->right。
- 交换操作:如果左右孩子都有,互相交换;如果只有一边,换到另一边;
代码实现
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:void invertchild(TreeNode* cur){if(!cur || cur->left == nullptr && cur->right == nullptr){ //遇到空或叶子节点返回return;}invertchild(cur->left);invertchild(cur->right);//交换if(cur->left && cur->right){TreeNode* temp = cur->left;cur->left = cur->right;cur->right = temp;}else if(cur->left && !cur->right ){cur->right = cur->left;cur->left = nullptr;}else if(cur->right && !cur->left){cur->left = cur->right;cur->right = nullptr;}}TreeNode* invertTree(TreeNode* root) {invertchild(root);return root;}
};
参考思路
参考代码链接
学习内容
参考思路
中心思想:交换每个节点的左右孩子。所以不管是哪种遍历,得遍历到每一个节点。
- 法一——递归法:使用前序、后序遍历;交换操作直接用swap。结合二、的代码实现改变下。二、中的遍历方式——后序遍历。参考代码对应前序遍历。
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* invertTree(TreeNode* root) {if(root == nullptr) return root;invertTree(root->left);invertTree(root->right);swap(root->left,root->right);return root;}
};
- 法二——迭代法。用前序的迭代。
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* invertTree(TreeNode* root) {if(!root) return root;stack<TreeNode*> st;st.push(root);while(!st.empty()){TreeNode* cur = st.top();//中st.pop();swap(cur->left,cur->right);if(cur->right) st.push(cur->right);//先放右。交换之后的右是原来的左。下一轮先处理原来的右。if(cur->left) st.push(cur->left);//后放左。交换之后的左是原来的右。下一轮先处理这个,这是原来的右。}return root;}
};
- 法三——统一迭代方式。
- 法四——层序遍历。
对比参考代码:参考:先swap,再push;
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* invertTree(TreeNode* root) {if(!root) return root;queue<TreeNode*> que;que.push(root);while(!que.empty()){int size = que.size();while(size--){TreeNode* cur = que.front();que.pop();if(cur->left) que.push(cur->left); //下一轮先处理原先的左子树。此时是交换之后的右子树。if(cur->right) que.push(cur->right);swap(cur->left,cur->right);}}return root;}
};
总结
翻转二叉树:遍历到每一个节点,交换左右孩子。
基础还是遍历方式。选择一种遍历方式即可。
(欢迎指正,转载标明出处)