6月6日刷题笔记——树
题目1:94. 二叉树的中序遍历(简单题)
我的题解:
递归思路,昨天前序遍历的递归学会了,中序就是一个道理啦。
/**
* 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 inorder(TreeNode* root, vector<int> &res){
if(root == nullptr) return;
inorder(root->left, res);
res.emplace_back(root->val);
inorder(root->right, res);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorder(root, res);
return res;
}
};
方法2:迭代法
参考题解:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目2:145. 二叉树的后序遍历(简单题)
我的题解:
递归方式:
class Solution {
public:
void postorder(TreeNode* root, vector<int> &res){
if(root == nullptr) return;
postorder(root->left, res);
postorder(root->right, res);
res.emplace_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
postorder(root,res);
return res;
}
};
方式2:迭代
还是没写出来,题解代码:
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if (root == nullptr) {
return res;
}
stack<TreeNode *> stk;
// 指针记录已经访问过并成功出栈的节点
TreeNode *prev = nullptr;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.emplace(root);
root = root->left;
}
root = stk.top();
stk.pop();
/* 注意这里的roo->right == prev条件是此时该节点的右节点已经遍历输出过了
** 此时满足左右节点均访问过,所以此时访问根节点
*/
if (root->right == nullptr || root->right == prev) {
res.emplace_back(root->val);
prev = root;
// 该节点已经出栈访问过了,要释放该节点,才能进行下一次的root = stk.top()否则会超出时间限制
root = nullptr;
} else {
// 右节点还没有访问过,则将该节点入栈,继续访问右节点
stk.emplace(root);
root = root->right;
}
}
return res;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目3:102. 二叉树的层序遍历(中等题)
不会解。
知识点:二叉树、广度优先搜索
思路:
参考题解:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector <vector <int>> ret;
if (!root) {
return ret;
}
queue <TreeNode*> q;
// 根元素入队
q.push(root);
while (!q.empty()) {
// 求当前队列长度(即当前层含有的元素个数)
int currentLevelSize = q.size();
ret.push_back(vector <int> ());
// 遍历当前层
for (int i = 1; i <= currentLevelSize; ++i) {
// 依次取队首元素,并出队
auto node = q.front(); q.pop();
// 取出的元素加入到数组内
ret.back().push_back(node->val);
// 把该节点在下一层的左右节点入栈
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
return ret;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
根据题解复现代码:
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int n = q.size();
vector<int> ans;
// res.push_back(ans);
for(int i = 0; i < n; ++i){
TreeNode* node = q.front();
q.pop();
ans.push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
res.push_back(ans);
}
return res;
}
};
方法二:递归解法
看评论区大佬的递归解法。
思路:
代码如下:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans;
pre(root, 0, ans);
return ans;
}
void pre(TreeNode *root, int depth, vector<vector<int>> &ans) {
if (!root) return ;
if (depth >= ans.size())
// 给二维数组扩充
ans.push_back(vector<int> {});
ans[depth].push_back(root->val);
pre(root->left, depth + 1, ans);
pre(root->right, depth + 1, ans);
}
};
题目4:104. 二叉树的最大深度(简单题)
知识点:二叉树、广度优先搜索、深度优先搜索
我的题解:
层序遍历,返回数组的行数即为二叉树的层数。
/**
* 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 level(TreeNode* root, int depth, vector<vector<int>> &res){
if(root == nullptr) return;
if(depth >= res.size()){
res.push_back(vector<int> {});
}
res[depth].push_back(root->val);
level(root->left, depth+1, res);
level(root->right, depth+1, res);
}
int maxDepth(TreeNode* root) {
vector<vector<int>> res;
int depth = 0;
level(root, depth, res);
return res.size();
}
};
总结知识点:
1.二叉树的深度:从根节点到该节点的最长简单路径的条数
2.二叉树的高度:从该节点到叶子节点的最长简单路径的条数
(即,一个是从上往下是第几层,一个是从下往上是第几层)
方法二:参考题解的深度优先搜索。
递归的方式。
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
题目5:101. 对称二叉树(简单题)
我的题解:部分用例没通过。
我用了一个栈一个队列判断,但这样没办法判断比如两个节点都只有右节点,没有左节点,此时他们值相同,但是不对称。问题出在这里,但是不知道怎么解决。
/**
* 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:
bool isSymmetric(TreeNode* root) {
if(!root) return false;
// vector<int> tmp;
stack<TreeNode*> stk;
queue<TreeNode*> q;
q.push(root);
TreeNode* node;
TreeNode* jug;
int i = 0;
while(!q.empty()){
int n = q.size();
vector<int> tmp;
for(i = 0; i < n; i++){
node = q.front();
q.pop();
tmp.push_back(node->val);
stk.push(node);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
i = 0;
while(!stk.empty()){
if(stk.top()->val == tmp[i]){
stk.pop();
i++;
}else{
return false;
}
}
}
return true;
}
};
参考官方题解:
方法一:递归
class Solution {
public:
bool check(TreeNode *p, TreeNode *q) {
// 两节点同时存在或同时不存在,说明是合理的
if (!p && !q) return true;
if (!p || !q) return false;
// p向左时,q向右;p向右时,q向左。保证p和q访问的是镜像的两个元素,比较两元素是否相等
return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
}
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方法二:迭代
class Solution {
public:
bool check(TreeNode *u, TreeNode *v) {
queue <TreeNode*> q;
// 根节点入队两次,后面u左v右,u右v左
q.push(u); q.push(v);
while (!q.empty()) {
u = q.front(); q.pop();
v = q.front(); q.pop();
if (!u && !v) continue;
if ((!u || !v) || (u->val != v->val)) return false;
q.push(u->left);
q.push(v->right);
q.push(u->right);
q.push(v->left);
}
return true;
}
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。