算法随想Day16【二叉树】| LC513-找树左下角的值、LC112-路径总和、LC106-从中序与后序遍历序列构造二叉树
LC513. 找树左下角的值
这道题用层次遍历,更容易做
int findBottomLeftValue(TreeNode* root)
{
int result = 0;
int size = 0;
queue<TreeNode*> que;
TreeNode* curr = nullptr;
if (root != nullptr)
{
que.push(root);
}
while (que.empty() != true)
{
size = que.size();
result = que.front()->val;
for (int i = 0; i < size; i++)
{
curr = que.front();
que.pop();
if (curr->left != nullptr)
{
que.push(curr->left);
}
if (curr->right != nullptr)
{
que.push(curr->right);
}
}
}
return result;
}
记录下错误:
开始没定义size,直接写为for (int i = 0; i < que.size(); i++),这是一段错误的代码,因为for内对queue进行的push和pop操作都会影响其size()值,这里很容易忽略出错
Carl讲解的递归做法:解法比较巧妙,变量maxDepth记录当前的最深的层次,而且在最深层,找到第一个叶子节点,才会进行存储并更新maxDepth。用到回溯,保持当前节点回溯时和递归前的depth值一致。
class Solution {
public:
int maxDepth = INT_MIN;
int result;
void traversal(TreeNode* root, int depth) {
if (root->left == NULL && root->right == NULL) {
if (depth > maxDepth) {
maxDepth = depth;
result = root->val;
}
return;
}
if (root->left) {
depth++;
traversal(root->left, depth);
depth--; // 回溯
}
if (root->right) {
depth++;
traversal(root->right, depth);
depth--; // 回溯
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root, 0);
return result;
}
};
LC112. 路径总和
class Solution
{
public:
int flag;
void checkPathSum(TreeNode* root, int sum, int& targetSum)
{
if (root == nullptr) return; //力扣非要加多这一句才给通过,不理解
sum += root->val; //中
if (root->left == nullptr && root->right == nullptr)
{
if (targetSum == sum)
{
flag = true;
}
return ;
}
checkPathSum(root->left, sum, targetSum); //左
checkPathSum(root->right, sum, targetSum); //右
}
bool hasPathSum(TreeNode* root, int targetSum)
{
int sum = 0;
flag = false;
if (root == nullptr)
{
return false;
}
checkPathSum(root, sum, targetSum);
return flag;
}
};
LC106. 从中序与后序遍历序列构造二叉树
递归的函数,传参传的是值,而不是地址,所以内存消耗比较大。其实可以传引用,然后用指针(索引下标)标明每层对两个数组的操作范围的话,应该可以省下些内存。
class Solution
{
public:
TreeNode* buildTreeLoop(vector<int> inorder, vector<int> postorder)
{
int count = 0;
int curr_val = postorder[postorder.size() - 1];
TreeNode* root = new TreeNode(curr_val);
////开始写了这个判断,作为递归终止条件,后面添加下面两个if判断,遂可以省去这个
// if (postorder.size() == 1)
// {
// return root;
// }
auto it = find(inorder.begin(), inorder.end(), curr_val);
for (auto i = inorder.begin(); i != it; i++)
{
++count;
}
////这两个if判断不能丢,否则可能导致指针访问越界
if (it != inorder.begin()) //当it指向inorder.begin()时,说明当前节点已经没有左子树
root->left = buildTreeLoop(vector<int>(inorder.begin(), it), vector<int>(postorder.begin(), postorder.begin() + count));
if (it != inorder.end() - 1) //当it指向inorder.end() - 1时,说明当前节点已经没有右子树
root->right = buildTreeLoop(vector<int>(it + 1, inorder.end()), vector<int>(postorder.begin() + count, postorder.end() - 1));
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
return buildTreeLoop(inorder, postorder);
}
};

浙公网安备 33010602011771号