二叉树的右视图
力扣题目链接
题目描述:
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
思路:
- 层次遍历取每一层的最后一个元素即可,层次遍历写法 可以看这里。
代码实现:
vector<int> rightSideView(TreeNode* root) {
if (root == nullptr) {
return {};
}
queue<TreeNode*> que;
que.push(root);
int size = 0;
vector<int> results;
while(!que.empty()) {
size = que.size();
vector<int> vec;
for (int i = 0; i < size; ++i) {
TreeNode* cur = que.front();
que.pop();
vec.push_back(cur->val);
if (cur->left) {
que.push(cur->left);
}
if (cur->right) {
que.push(cur->right);
}
}
results.push_back(vec[vec.size() - 1]);
}
return results;
}
其他扩展题(都是层次遍历扩展,直接秒):
层次遍历2、二叉树层的平均值、N叉树层次遍历、在每个树行中找最大值、116.填充每个节点的下一个右侧节点指针、117.填充每个节点的下一个右侧节点指针II、二叉树最大深度、二叉树最小深度
二叉树翻转
力扣题目链接
题目描述:
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
思路:
- 递归法
- 前序遍历或者后序遍历递归,增加交换操作即可。不能采用中序遍历,中序遍历会把子树交换两次。
代码实现
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) {
return nullptr;
}
swap(root->left, root->right);//前序和后序都可以
invertTree(root->left);
invertTree(root->right);
return root;
}
- 迭代法
- 可以采用层次遍历或者前序、后序遍历
//层次遍历
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) {
return nullptr;
}
queue<TreeNode*> que;
que.push(root);
while(!que.empty()) {
int size = que.size();
for (int i = 0; i < size; ++i) {
TreeNode* cur = que.front();
swap(cur->left, cur->right);
que.pop();
if (cur->left) {
que.push(cur->left);
}
if (cur->right) {
que.push(cur->right);
}
}
}
return root;
}
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) {
return nullptr;
}
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()) {
TreeNode* cur = stk.top();
stk.pop();
swap(cur->left, cur->right);
if (cur->right) {
stk.push(cur->right);
}
if(cur->left) {
stk.push(cur->left);
}
}
return root;
}
对称二叉树
力扣题目链接
题目描述:
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
思路:
- 递归法:采用前序遍历,先处理中间再处理两边,下面为递归三部曲
- 确定函数参数和函数返回值,很明显本题参数为左子树和右子树比较,所以参数为左右两个子树,返回值返回布尔类型
- 确定函数退出条件,当左右节点都为空时,返回true,左节点为空右节点非空、右节点非空左节点空以及左右节点值不相等时返回true。
- 单步逻辑:此时判断左节点的左孩子和右节点的右孩子,以及左节点的右孩子和右节点的左孩子。
- 最终,只有单步逻辑都为true时,函数整体返回true
代码实现
bool travisal(TreeNode* left, TreeNode* right) {
if (left && !right) {
return false;
} else if (!left && !right) {
return true;
} else if (!left && right) {
return false;
} else if (left->val != right->val) {
return false;
} else {
bool out_side = travisal(left->left, right->right);//外
bool in_side = travisal(left->right, right->left);//内
return out_side && in_side;
}
}
bool isSymmetric(TreeNode* root) {
if (root == nullptr) {
return false;
}
return travisal(root->left, root->right);
}
- 迭代法:采用类似于层次遍历的方法,把每层元素一次放入队列,逐层比较,注意放入队列时的顺序。
另外这里容器采用栈也是可以的
bool isSymmetric(TreeNode* root) {
if (root == nullptr) {
return false;
}
queue<TreeNode*> que;
que.push(root->left);
que.push(root->right);
while (!que.empty()) {
TreeNode* left = que.front();
que.pop();
TreeNode* right = que.front();
que.pop();
if (!left && !right) {
continue;
}
if (!left || !right || left->val != right->val) return false;
que.push(left->left);
que.push(right->right);
que.push(left->right);
que.push(right->left);
}
return true;
}