代码随想录算法训练营Day18 | 513.找树左下角的值 112. 路径总和 113.路径总和ii 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
LeetCode 513.找树左下角的值
题目链接:LeetCode 513.找树左下角的值
思路:
递归法,即寻找最左的节点。先找左节点,一定是最左边的。
迭代法,理解清晰,记录最左节点。
//递归法
class Solution {
public:
int maxDepth = -1;
int result;
void traversal(TreeNode* node, int depth){
if (!node) return;
if(depth > maxDepth){
maxDepth = depth;
result = node->val;
}
if(node->left) traversal(node->left, depth+1);
if(node->right) traversal(node->right, depth+1);
}
int findBottomLeftValue(TreeNode* root) {
traversal(root, 0);
return result;
}
};
//迭代法
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if(root) que.push(root);
int front;
while(!que.empty()){
int size = que.size();
for(int i=0; i<size; i++){
TreeNode* node = que.front();
que.pop();
if(i==0) front = node->val;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return front;
}
};
注意 :
- maxDepth为全局变量
LeetCode 112. 路径总和
题目链接:LeetCode 112. 路径总和
思路:
递归法,简单。
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root) return false;
if (!root->left && !root->right && targetSum == root->val){
return true;
}
return hasPathSum(root->left, targetSum - root->val) || hasPathSum(root->right, targetSum - root->val);
}
};
LeetCode 113.路径总和ii
题目链接:LeetCode 113.路径总和ii
思路:
1.思路类似,简单。 递归法,注意回溯过程。
class Solution {
public:
void traversal(TreeNode* node, int count, vector<int>& path, vector<vector<int>>& res) {
if (!node) return;
path.push_back(node->val);
count -= node->val;
if (count == 0 && !node->left && !node->right)
res.push_back(path);
if(node->left){
traversal(node->left, count, path, res);
path.pop_back();
}
if(node->right){
traversal(node->right, count, path, res);
path.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> path;
vector<vector<int>> res;
if (!root) return res;
traversal(root, targetSum, path, res);
return res;
}
};
注意 :
- path为指针,需pop
- count传值,不需要减掉
LeetCode 106.从中序与后序遍历序列构造二叉树
题目链接:LeetCode 106.从中序与后序遍历序列构造二叉树
思路:
1.先用后序确定root,再切分中序,最后切分后序。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(!postorder.size()) return NULL;
int rootValue = postorder[postorder.size()-1];
TreeNode* root = new TreeNode(rootValue);
if(inorder.size()==1) return root;
auto it = find(inorder.begin(),inorder.end(), rootValue);
int cut = it-inorder.begin();
vector<int> leftInorder(inorder.begin(),inorder.begin()+cut);
vector<int> rightInorder(inorder.begin()+cut+1,inorder.end());
postorder.pop_back();
vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInorder.size());
vector<int> rightPostorder(postorder.begin()+leftInorder.size(),postorder.end());
root->left = buildTree(leftInorder,leftPostorder);
root->right = buildTree(rightInorder,rightPostorder);
return root;
}
};
注意 :
- 每次后序切分时注意弹出最后一个元素。
LeetCode 105.从前序与中序遍历序列构造二叉树
题目链接:LeetCode 105.从前序与中序遍历序列构造二叉树
思路:
同105
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(!preorder.size()) return NULL;
int rootValue = preorder[0];
TreeNode* root = new TreeNode(rootValue);
if(preorder.size()==1) return root;
int cut = 0;
for(; cut<inorder.size();cut++) if(inorder[cut]==rootValue) break;
vector<int> leftInorder(inorder.begin(), inorder.begin()+cut);
vector<int> rightInorder(inorder.begin()+cut+1, inorder.end());
preorder.erase(preorder.begin());
vector<int> leftPreorder(preorder.begin(), preorder.begin()+cut);
vector<int> rightPreorder(preorder.begin()+cut, preorder.end());
root->left = buildTree(leftPreorder, leftInorder);
root->right = buildTree(rightPreorder, rightInorder);
return root;
}
};
注意 :
- 前序的删除首元素,用erase。