目录
三、LeetCode106. 从中序与后序遍历序列构造二叉树
前言
LeetCode513. 找树左下角的值
视频讲解:LeetCode:513.找二叉树左下角的值_哔哩哔哩_bilibili
LeetCode112 113. 路径总和 路径总和Ⅱ
视频讲解:LeetCode:112. 路径总和_哔哩哔哩_bilibili
LeetCode106. 从中序与后序遍历序列构造二叉树
视频讲解:LeetCode:106.从中序与后序遍历序列构造二叉树_哔哩哔哩_bilibili
一、LeetCode513. 找树左下角的值
题目链接:
题目思路:
找树的左下角的值要注意的是,这个只有可能是一个结点的左孩子结点,也可能是右孩子结点,例如下图中我们要找的就是结点2的左孩子结点的值
而下图则是要找到结点2的右孩子的结点值
前中后序遍历都会先遍历左结点然后才会遍历右结点,所以通过遍历并判断结点的深度,我们可以优先找到最深一层结点的最左结点。
代码:
/**
* 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 {
private:
int maxDepth = INT32_MIN;
int result;
void backTrace(TreeNode* root, int depth) {
if (root->left == nullptr && root->right == nullptr) {
if (depth > maxDepth)
{
maxDepth = depth;
result = root->val;
}
}
if(root->left)
{
depth++;
backTrace(root->left, depth);;
depth--;
}
if(root->right)
{
depth++;
backTrace(root->right, depth);
depth--;
}
}
public:
int findBottomLeftValue(TreeNode* root) {
maxDepth = INT32_MIN;
backTrace(root, 0);
return this->result;
}
};
二、LeetCode112 113. 路径总和 路径总和Ⅱ
题目链接:
代码思路:
通过递归遍历,一直记录当前的结点值之和(此处的count通过减去遍历的结点值来“反向”记录结点值之和)。当遍历到叶子结点,我们可以判断count是否为0,如果为0则代表这条路径的结点之和为目标值,则代表这条路径符合要求。
代码:
路径总和:
/**
* 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:
bool traversal(TreeNode* root, int count)
{
if(root->left == nullptr && root->right == nullptr)
{
if(count == 0)
return true;
else
return false;
}
if(root->left)
{
count -= root->left->val;
if(traversal(root->left, count))
return true;
count += root->left->val;
}
if(root->right)
{
count -= root->right->val;
if(traversal(root->right, count))
return true;
count += root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return 0;
return traversal(root, targetSum - root->val);
}
};
路径总和Ⅱ:
/**
* 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:
vector<vector<int>> result;
void traversal(TreeNode* root, vector<int> path, int count)
{
path.push_back(root->val);
if(root->left == nullptr && root->right == nullptr && count == 0)
{
this->result.push_back(path);
return ;
}
if(root->left)
{
traversal(root->left, path, count - root->left->val);
}
if(root->right)
{
traversal(root->right, path, count - root->right->val);
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return {};
this->result.clear();
vector<int> path;
traversal(root, path, targetSum - root->val);
return this->result;
}
};
三、LeetCode106. 从中序与后序遍历序列构造二叉树
题目链接:
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
题目思路:
首先我们要知道通过中序和后序手动得到二叉树结构的步骤,后序序列用来判断根结点的位置,中序序列通过后序序列得到的根节点,对左右子树进行划分,然后再通过后序序列对左右子树找根节点,再不断的对左右子树进行划分。
代码步骤:
-
第一步:如果数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
-
第五步:切割后序数组,切成后序左数组和后序右数组
-
第六步:递归处理左区间和右区间
代码:
/**
* 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(postorder.size() == 0)
return NULL;
int rootVal = postorder[postorder.size() - 1];
TreeNode* root = new TreeNode(rootVal);
if(postorder.size() == 1)
return root;
int index = 0;
for(index = 0; index < inorder.size(); index++)
{
if(inorder[index] == rootVal)
break;
}
// 切割中序数组
vector<int> leftInorder(inorder.begin(), inorder.begin() + index);
vector<int> rightInorder(inorder.begin() + index + 1, inorder.end());
postorder.resize(postorder.size() - 1);
vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
// // 以下为日志
// cout << "----------" << endl;
// cout << "leftInorder :";
// for (int i : leftInorder) {
// cout << i << " ";
// }
// cout << endl;
// cout << "rightInorder :";
// for (int i : rightInorder) {
// cout << i << " ";
// }
// cout << endl;
// cout << "leftPostorder :";
// for (int i : leftPostorder) {
// cout << i << " ";
// }
// cout << endl;
// cout << "rightPostorder :";
// for (int i : rightPostorder) {
// cout << i << " ";
// }
// cout << endl;
root->left = buildTree(leftInorder, leftPostorder);
root->right = buildTree(rightInorder, rightPostorder);
return root;
}
};