第一题
层序遍历是用队列来写的,在一个循环里遍历同一层的节点,遍历到的先pop,再将它的左右子节点加入队列,等本层节点遍历完后,队列里就全是下一层的节点了。(因此要在循环开始前就记录好队列的size:
lass Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if (root == nullptr) return {};
queue<TreeNode*> que;
vector<vector<int>> result;
que.push(root);
while (!que.empty()) {
vector<int> res;
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
res.push_back(node->val);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
result.push_back(res);
}
return result;
}
};
第二题
层序遍历:
用栈实现迭代
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) return nullptr;
stack<TreeNode*> st;
st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
TreeNode* temp = node->left;
st.pop();
node->left = node->right;
node->right = temp;
if (node->left) {
st.push(node->left);
}
if (node->right) {
st.push(node->right);
}
}
return root;
}
};
其中交换左右节点也可以用函数swap:
swap(node->left, node->right);
`std::swap()` 是 C++ 标准库中的一个函数,它用于交换两个变量的值。`std::swap()` 的函数原型是 `void swap (T& a, T& b);` ,其中 `T` 是任何类型。这个函数接收两个引用参数 `a` 和 `b`,并交换它们的值。
需要注意的是,`std::swap()` 的参数必须是可修改的左值,也就是说,你不能直接传入字面值或者常量来调用这个函数。而且,如果你想交换的两个变量是自定义类型的对象,那么这个类型需要支持拷贝赋值操作或者移动赋值操作,否则 `std::swap()` 无法工作。
递归遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) return nullptr;
//前序 中左右
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
//后序 左右中
invertTree(root->left);
invertTree(root->right);
swap(root->left, root->right);
//中序 左中右
invertTree(root->left);
swap(root->left, root->right);
invertTree(root->left);
return root;
}
};
第三题
自己写的笨方法,将左子树翻转一下,顺序存下每个节点值,然后遍历右子树存下节点值,对比两个vector看是否相等,如果遇到null,就存入一个最大值INT32_MAX,否则直接跳过不存的话会出错。已AC:
class Solution {
public:
TreeNode* invertTree(TreeNode* node, vector<int>& res) {
if (node == nullptr) {
res.push_back(INT32_MAX);
return nullptr;
}
res.push_back(node->val);
swap(node->left, node->right);
invertTree(node->left, res);
invertTree(node->right, res);
return node;
}
TreeNode* getTreeVal(TreeNode* node, vector<int>& res) {
if (node == nullptr) {
res.push_back(INT32_MAX);
return nullptr;
}
res.push_back(node->val);
getTreeVal(node->left, res);
getTreeVal(node->right, res);
return node;
}
bool isSymmetric(TreeNode* root) {
vector<int> res1;
vector<int> res2;
invertTree(root->left, res1);
getTreeVal(root->right, res2);
if ( res1 == res2) {
return true;
}
else return false;
}
};
学习记录:
凡是需要收集孩子信息返回给上一层的题目都要用后序遍历(左右中):
确定返回值和参数:
返回值为bool类型,参数为左子树和右子树
确定终止条件:
当左节点为空,右节点不为空或者左节点不为空,右节点为空时,不对称,返回false终止;
当左右节点的值不相等时,不对称,返回false终止;
当左右节点都为空时,对称,返回true终止;
当左右节点都不为空时,比较节点的值,不相同返回false终止;
单层递归逻辑:
每次递归都要判断左子树的左右子节点是否等于右子树的左右子节点的翻转:
首先比较外侧,看左子树的左孩子是否等于右子树的右孩子,然后比较内侧,看左子树的右孩子是否等于右子树的左孩子,如果有一处不相等返回false。
class Solution {
public:
//递归函数
bool isCompare(TreeNode* left, TreeNode* right) {
if ((left == nullptr && right != nullptr) || (left != nullptr && right == nullptr)) return false;
else if (left == nullptr && right == nullptr) return true;
else if (left->val != right->val) return false;
else {
bool outside = isCompare(left->left, right->right);
bool inside = isCompare(left->right, right->left);
bool res = outside && inside;
return res;
}
}
bool isSymmetric(TreeNode* root) {
if (root == nullptr) return false;
return isCompare(root->left, root->right);
}
};