训练营十六天继续刷题。今天最后一题看了好久,继续坚持。
513.找树左下角的值
做题过程
- 使用迭代法层序遍历做,更新每一层第一个数字的值就行
知识点
- 深度最大的叶子节点一定是最后一行,一旦更新最大深度就记录数值,就是最左边的值。
迭代法
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*>que;
if (root) que.push(root);
int result;
while (!que.empty()) {
int size = que.size();
result = que.front()->val;
while (size--) {
TreeNode* cur = que.front();
que.pop();
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
}
return result;
}
};
递归法
class Solution {
public:
int result;
int maxDepth = 0;
void traversal(TreeNode* node, int depth) {
if (node->left == nullptr && node->right == nullptr) {
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, 1);
return result;
}
};
112.路径总和
做题过程
- 使用递归法,遇到叶子节点判断和是否为目标和,是的话返回true
递归法
class Solution {
public:
void getSum(TreeNode* node, int targetSum, int sum) {
if (node->left == nullptr && node->right == nullptr) {
if (sum == targetSum) result = true;
}
if (node->left) getSum(node->left, targetSum, sum + node->left->val);
if (node->right) getSum(node->right, targetSum, sum + node->right->val);
}
bool hasPathSum(TreeNode* root, int targetSum) {
if (root == nullptr) return false;
getSum(root, targetSum, root->val);
return result;
}
bool result = false;
};
113.路经总和Ⅱ
解题过程
- 用递归法求解,记录路径上的值和路径节点和
递归法
class Solution {
public:
void getPath(TreeNode* node, vector<int>&path, int& sum, int& targetSum) {
if (node->left == nullptr && node->right == nullptr) {
if (sum == targetSum) result.push_back(path);
else return;
}
if (node->left) {
path.push_back(node->left->val);
sum += node->left->val;
getPath(node->left, path, sum, targetSum);
path.pop_back();
sum -= node->left->val;
}
if (node->right) {
path.push_back(node->right->val);
sum += node->right->val;
getPath(node->right, path, sum, targetSum);
path.pop_back();
sum -= node->right->val;
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if (root == nullptr) return {};
vector<int>path;
path.push_back(root->val);
getPath(root, path, root->val, targetSum);
return result;
}
vector<vector<int>>result;
};
106.从中序与后序遍历序列构造二叉树
做题过程
- debug很久,因为边界的问题。这题还需多刷
知识点
- 第一步:如果数组大小为零的话,说明是空节点了。
- 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
- 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
- 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
- 第五步:切割后序数组,切成后序左数组和后序右数组
- 第六步:递归处理左区间和右区间
递归法
class Solution {
public:
TreeNode* build(vector<int>& inorder, vector<int>& postorder, int inorderBegin, int inorderEnd, int postorderBegin, int postorderEnd) {
if (inorderBegin == inorderEnd) return nullptr;
TreeNode* node = new TreeNode(postorder[postorderEnd - 1]);
if (inorderEnd - inorderBegin == 1) return node;
int index = inorderBegin;
for (index = inorderBegin; index < inorderEnd; index++) {
if (inorder[index] == postorder[postorderEnd - 1]) break;
}
int leftInorderBegin = inorderBegin;
int leftInorderEnd = index;
int leftPostorderBegin = postorderBegin;
int leftPostorderEnd = leftPostorderBegin + index - inorderBegin;
node->left = build(inorder, postorder, leftInorderBegin, leftInorderEnd, leftPostorderBegin, leftPostorderEnd);
int rightInorderBegin = index + 1;
int rightInorderEnd = inorderEnd;
int rightPostorderBegin = leftPostorderEnd;
int rightPostorderEnd = postorderEnd - 1;
node->right = build(inorder, postorder, rightInorderBegin, rightInorderEnd, rightPostorderBegin, rightPostorderEnd);
return node;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return nullptr;
return build(inorder, postorder, 0, inorder.size(), 0, postorder.size());
}
};