二叉树之反转
226翻转二叉树:给你一棵二叉树的根节点 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)
{
stack<TreeNode*> sta;
if(root!=nullptr) sta.push(root);
while(!sta.empty())
{
TreeNode *node=sta.top();
swap(node->left,node->right);
sta.pop();
if(node->right) sta.push(node->right);
if(node->left) sta.push(node->left);
}
return root;
}
};
构造二叉树(递归)
构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
递归的三个步骤:
(1)确定递归函数的参数和返回值
(2)确定终止条件
(3)确定单层递归的逻辑
106从中序与后序遍历序列构造二叉树
题目 难度:中等
终止条件:中序数组和后序数组的大小为1
/**
* 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* buildTree(vector<int>& inorder, vector<int>& postorder)
{
if (inorder.size() == 0 || postorder.size() == 0) return NULL;
int last_value=postorder[postorder.size()-1];//后序数组最后一个元素,也就是切割点
//找切割点的在中序数组的下标
int lastvalue_index;
for(int i=0;i<inorder.size();i++)
{
if (last_value==inorder[i])
{
lastvalue_index=i;
}
}
TreeNode* root = new TreeNode(last_value);//根节点
//叶子节点
if (inorder.size()==1&&postorder.size() == 1) return root;
//左闭右开
//中序左数组
vector<int> inorder_left(inorder.begin(),inorder.begin()+lastvalue_index);
//中序右数组
vector<int> inorder_right(inorder.begin()+lastvalue_index+1,inorder.end());
//后序左数组
vector<int> postorder_left(postorder.begin(), postorder.begin() + inorder_left.size());
//后序右数组
vector<int> postorder_right(postorder.begin() + inorder_left.size(), postorder.end()-1);
//postorder.end()-1这里-1是舍弃末尾元素(切割点)
root->left=buildTree(inorder_left,postorder_left);
root->right=buildTree(inorder_right,postorder_right);
return root;
}
};
654最大二叉树
题目 难度:中等
终止条件:如果传入的数组大小为1,说明遍历到了叶子节点了。
/**
* 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* constructMaximumBinaryTree(vector<int>& nums)
{
TreeNode* node=new TreeNode(0);
//确定终止条件:题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况
//那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。
if (nums.size() == 1)
{
node->val = nums[0];
return node;
}
// 找到数组中最大的值和对应的下标
// int maxValue = 0;
// int maxposition= 0;//下标
// for (int i = 0; i < nums.size(); i++) {
// if (nums[i] > maxValue) {
// maxValue = nums[i];
// maxposition = i;
// }
// }
// node->val = maxValue;
int maxposition=max_element(nums.begin(),nums.end())-nums.begin();//下标
node->val=nums[maxposition];
//构造左子树
if(maxposition>=1)//保证左区间至少有一个数值
{
vector<int> leftvec(nums.begin(),nums.begin()+maxposition);
node->left=constructMaximumBinaryTree(leftvec);
}
//构造右子树
if(nums.size()-maxposition>1)//确保右区间至少有一个数值。
{
vector<int> rightvec(nums.begin()+maxposition+1,nums.end());
node->right=constructMaximumBinaryTree(rightvec);
}
return node;
}
};
617合并二叉树
题目 难度:简单
终止条件:有一棵树为空,就返回另一棵树
- 方法1:前序遍历(递归)
/**
* 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* mergeTrees(TreeNode* root1, TreeNode* root2)
{
//前序遍历(递归)
//终止条件
if(root1==nullptr) return root2;
if(root2==nullptr) return root1;
root1->val+=root2->val;//中
root1->left=mergeTrees(root1->left,root2->left);//左
root1->right=mergeTrees(root1->right,root2->right);//右
return root1;
}
- 方法2:层序遍历(迭代)将root1和root2都放进一个queue
/**
* 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* mergeTrees(TreeNode* root1, TreeNode* root2)
{
//层序遍历(迭代)
queue<TreeNode*> que;
que.push(root1);
que.push(root2);
if (root1 == NULL) return root2;
if (root2 == NULL) return root1;
while(!que.empty())
{
TreeNode* node1=que.front();
que.pop();
TreeNode *node2=que.front();
que.pop();
node1->val+=node2->val;
// 如果两棵树左节点都不为空,加入队列
if (node1->left != NULL && node2->left != NULL)
{
que.push(node1->left);
que.push(node2->left);
}
// 如果两棵树右节点都不为空,加入队列
if (node1->right != NULL && node2->right != NULL)
{
que.push(node1->right);
que.push(node2->right);
}
// 当t1的左节点 为空 t2左节点不为空,就赋值过去
if (node1->left == NULL && node2->left != NULL)
{
node1->left = node2->left;
}
// 当t1的右节点 为空 t2右节点不为空,就赋值过去
if (node1->right == NULL && node2->right != NULL)
{
node1->right = node2->right;
}
}
return root1;
}
};
- 方法3:层序遍历(迭代)将root1和root2放进放进两个queue(自创)
/**
* 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* mergeTrees(TreeNode* root1, TreeNode* root2)
{
//层序遍历(迭代)
queue<TreeNode*> que1;
queue<TreeNode*> que2;
que1.push(root1);
que2.push(root2);
if (root1 == NULL) return root2;
if (root2 == NULL) return root1;
while(!que1.empty())
{
TreeNode* node1=que1.front();
que1.pop();
TreeNode *node2=que2.front();
que2.pop();
node1->val+=node2->val;
// 如果两棵树左节点都不为空,加入队列
if (node1->left != NULL && node2->left != NULL)
{
que1.push(node1->left);
que2.push(node2->left);
}
// 如果两棵树右节点都不为空,加入队列
if (node1->right != NULL && node2->right != NULL)
{
que1.push(node1->right);
que2.push(node2->right);
}
// 当t1的左节点 为空 t2左节点不为空,就赋值过去
if (node1->left == NULL && node2->left != NULL)
{
node1->left = node2->left;
}
// 当t1的右节点 为空 t2右节点不为空,就赋值过去
if (node1->right == NULL && node2->right != NULL)
{
node1->right = node2->right;
}
}
return root1;
}
};