目录
一、226. 翻转二叉树
1.题目描述
给你一棵二叉树的根节点 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 = [] 输出:[]
2.解题思路
递归思想
- 前序:①翻转root的左右孩子,②翻转root的左子树,③翻转root的右子树
- 后续:①翻转root的左子树,②翻转root的右子树,③翻转root的左右孩子
- 中序:这里要注意一下,如果先翻转root的左子树,再翻转root的左右孩子,此时如果再对root的右子树进行翻转,其实是对之前已经翻转过的左子树又翻转了一次,所以这里要换个写法。
3.代码实现(前序)
/**
* 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) {
//递归思想
//触底反弹,如果实参为空,直接return
if(root == NULL) return root;
//超级操作
//前序遍历:中、左、右
swap(root->left,root->right);//中:先翻转“传来的实参节点”的左右孩子
invertTree(root->left);//左:再翻转“传来的实参节点”的左子树
invertTree(root->right);//右:再翻转“传来的实参节点”的右子树
//返回值
return root;
}
};
二、101. 对称二叉树
1.题目描述
给你一个二叉树的根节点 root
, 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3] 输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3] 输出:false
2.解题思路
大体思想:先判断左右子树是否可以翻转:如果可以翻转,比较val是否相等;如果不可以翻转,直接return false。
递归思想:
- 1.确定函数参数和返回值:compare函数,函数返回值类型为bool,形参为左右子树。
- 2.确定出口条件:先判断左右子树含有空的情况;再判断如果都不为空,函数值是否相等;再判断是否对称。
- 3.确定单层递归的逻辑:如果左右子树节点都不为空,并且值也相等,那么比较是否对称:拿外层与外层,内层与内层,也就是left ->left 与right->right、left->right 与 right ->left比较。
3.代码实现
/**
* 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:
//1.返回值类型就是bool,判断左右子树是否对称,所以传入左右子树
bool compare(TreeNode* left,TreeNode* right){
//2.确定终止条件
//先判断左右子树是否可以翻转(对称的前提--可以翻转)
//判断左右子树 含有 空的情况
if(left == NULL && right != NULL) return false;
else if(left != NULL && right == NULL) return false;
else if(left == NULL && right == NULL) return true;
//排除了空节点,再排除数值不相等的情况
else if(left->val != right->val) return false;
//下面是左右子树都不为空,那么就要判断是否对称--元素值是否相等
bool outside = compare(left->left,right->right);
bool inside = compare(left->right,right->left);
bool isSame = outside && inside;
return isSame;
}
bool isSymmetric(TreeNode* root) {
if(root == NULL) return true;
//比较左右子树是否对称
return compare(root->left,root->right);
}
};
三、589. N 叉树的前序遍历
1.题目描述
给定一个 n 叉树的根节点 root
,返回 其节点值的 前序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null
分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6] 输出:[1,3,5,6,2,4]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14] 输出:[1,2,3,6,7,11,14,4,8,12,5,9,13,10]
2.解题思路
- 递归法
- 迭代法
3.代码实现(递归法--前序)
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public:
void traversal(Node* cur,vector<int>& result){
//递归法:前序遍历(中、左、右)
//触底反弹
if(cur == NULL) return;
//超级操作
result.push_back(cur->val);//先将 中 存放
//再分别对左右进行前序遍历
for(int i = 0;i < cur->children.size();i++){
traversal(cur->children[i],result);
}
//返回值
}
vector<int> preorder(Node* root) {
vector<int> result;//结果集
traversal(root,result);
return result;
}
};
4.代码实现(迭代法)
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public:
vector<int> preorder(Node* root) {
stack<Node*> st;
vector<int> result;
//利用栈-先进后出实现前序遍历
if(root == NULL) return result;
st.push(root);
while(!st.empty()){
Node* node = st.top();//中(栈顶元素),先保存到st中
st.pop();
result.push_back(node->val);
//分别 右、左 push到栈中。---顺序不能乱,先右后左,这样子就是先遍历左,然后右
for(int i = node->children.size() - 1;i >=0;i--){
if(node->children[i] != NULL) st.push(node->children[i]);
}
}
return result;
}
};