513.找树左下角的值
题目:513. 找树左下角的值
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int ans;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int size = q.size();
ans = q.front()->val;
while(size--){
TreeNode* cur = q.front();
q.pop();
if(cur->left) q.push(cur->left);
if(cur->right) q.push(cur->right);
}
}
return ans;
}
};
112. 路径总和
题目:112. 路径总和
class Solution {
public:
vector<int> result;
void get_sum(TreeNode* root,vector<int>& path){
path.push_back(root->val);
if(root->left == nullptr && root->right == nullptr){
int ans = 0;
for(int i = 0; i < path.size(); ++i){
ans += path[i];
}
result.push_back(ans);
return;
}
if(root->left){
get_sum(root->left,path);
path.pop_back();
}
if(root->right){
get_sum(root->right,path);
path.pop_back();
}
return;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return false;
vector<int> path;
get_sum(root,path);
for(int i = 0; i < result.size(); ++i){
if(result[i] == targetSum) return true;
}
return false;
}
};
113. 路径总和ii
题目:113. 路径总和 II
class Solution {
public:
vector<vector<int> > result;
void get_sum(TreeNode* root,vector<int>& path,int targetSum){
path.push_back(root->val);
if(root->left == nullptr && root->right == nullptr){
int ans = 0;
for(int i = 0; i < path.size(); ++i){
ans += path[i];
}
if(ans == targetSum){
result.push_back(path);
}
return;
}
if(root->left){
get_sum(root->left,path,targetSum);
path.pop_back();
}
if(root->right){
get_sum(root->right,path,targetSum);
path.pop_back();
}
return;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return result;
vector<int> path;
get_sum(root,path,targetSum);
return result;
}
};
106.从中序与后序遍历序列构造二叉树
//参数控制分割
class Solution {
public:
TreeNode* build(vector<int>& inorder, int in_l, int in_r, vector<int>& postorder, int post_l, int post_r){
if(in_l > in_r) return nullptr;
if(post_l > post_r) return nullptr;
int mid_val = postorder[post_r];
TreeNode* root = new TreeNode(mid_val);
int mid;
for(int i = in_l; i <= in_r; ++i){
if(inorder[i] == mid_val){
mid = i;
}
}
root->left = build(inorder,in_l,mid - 1, postorder,post_l, post_l + mid - in_l - 1);
root->right = build(inorder,mid + 1, in_r, postorder,post_l + mid - in_l,post_r - 1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
TreeNode* root = build(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
return root;
}
};
//代码内分割
class Solution {
private:
TreeNode* traversal (vector<int>& inorder, vector<int>& postorder) {
if (postorder.size() == 0) return NULL;
// 后序遍历数组最后一个元素,就是当前的中间节点
int rootValue = postorder[postorder.size() - 1];
TreeNode* root = new TreeNode(rootValue);
// 叶子节点
if (postorder.size() == 1) return root;
// 找到中序遍历的切割点
int delimiterIndex;
for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) {
if (inorder[delimiterIndex] == rootValue) break;
}
// 切割中序数组
// 左闭右开区间:[0, delimiterIndex)
vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
// [delimiterIndex + 1, end)
vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end() );
// postorder 舍弃末尾元素
postorder.resize(postorder.size() - 1);
// 切割后序数组
// 依然左闭右开,注意这里使用了左中序数组大小作为切割点
// [0, leftInorder.size)
vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
// [leftInorder.size(), end)
vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
root->left = traversal(leftInorder, leftPostorder);
root->right = traversal(rightInorder, rightPostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return NULL;
return traversal(inorder, postorder);
}
};
105.从前序与中序遍历序列构造二叉树
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(inorder.size() == 0) return nullptr;
int root_val = preorder[0];
TreeNode* root = new TreeNode(root_val);
int mid ;
for(int i = 0; i < inorder.size(); ++i){
if(inorder[i] == root_val){
mid = i;
}
}
//分割
vector<int> left_preorder(preorder.begin() + 1, preorder.begin() + 1 + mid);
vector<int> right_preorder(preorder.begin() + 1 + mid, preorder.end());
vector<int> left_inorder(inorder.begin(),inorder.begin() + mid);
vector<int> right_inorder(inorder.begin() + mid + 1, inorder.end());
root->left = buildTree(left_preorder,left_inorder);
root->right = buildTree(right_preorder,right_inorder);
return root;
}
};
总结
题型:二叉树的递归求路径和,还原二叉树
技巧:搞清楚什么时候用递归遍历,什么时候用层序遍历。