513.找树左下角的值
文章讲解:https://programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html
视频讲解:https://www.bilibili.com/video/BV1424y1Z7pn/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=e70917aa6392827d1ccc8d85e19e8375
题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/description/
实现情况:
找到深度最大的叶子节点
/**
* 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:
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;
}
};
112. 路径总和
文章讲解:路径总和
视频讲解:https://www.bilibili.com/video/BV19t4y1L7CR/?spm_id_from=333.788&vd_source=e70917aa6392827d1ccc8d85e19e8375
题目链接:https://leetcode.cn/problems/path-sum/description/
实现情况:
```c
/**
* 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:
bool traversal(TreeNode* cur, int count) {
if (!cur->left && !cur->right && count == 0)
return true;
if (!cur->left && !cur->right)
return false;
if (cur->left) { // 左
count -= cur->left->val;
if (traversal(cur->left, count))
return true;//注意这里
count += cur->left->val;
}
if (cur->right) { // 右
count -= cur->right->val;
if (traversal(cur->right, count))
return true;
count += cur->right->val;
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root)
return false;
return traversal(root, targetSum - root->val);
}
};
113. 路径总和ii
题目链接:https://leetcode.cn/problems/path-sum-ii/description/
实现情况:
和112. 路径总和的方法一致,就行需要遍历所以节点,并且记录路径
/**
* 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:
vector<vector<int>> result;
vector<int> path;
//这里不需要返回值是因为我们需要遍历所有节点
void traversal(TreeNode* cur, int count){
if(!cur->right && cur->left==NULL && count==0){
result.push_back(path);//符合条件的,添加到返回的结果中
return ;
}
if(!cur->right && cur->left == NULL)return;//叶子节点,但是不符合条件
if(cur->left){
path.push_back(cur->left->val);
count -= cur->left->val;
traversal(cur->left,count);
count +=cur->left->val;
path.pop_back();
}
if(cur->right){
path.push_back(cur->right->val);
count -= cur->right->val;
traversal(cur->right,count);
count +=cur->right->val;
path.pop_back();
}
return ;
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
result.clear();
path.clear();
if(!root) return result;
path.push_back(root->val);
traversal(root,targetSum-root->val);
return result;
}
};
106.从中序与后序遍历序列构造二叉树
文章讲解:https://programmercarl.com/0106.%E4%BB%8E%E4%B8%AD%E5%BA%8F%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频讲解:https://www.bilibili.com/video/BV1vW4y1i7dn/?spm_id_from=333.788&vd_source=e70917aa6392827d1ccc8d85e19e8375
题目链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/
实现情况:
/**
* 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:
TreeNode* traversal (vector<int>& inorder, int inorderBegin, int inorderEnd, vector<int>& postorder, int postorderBegin, int postorderEnd) {
if (postorderBegin == postorderEnd) return NULL;
int rootValue = postorder[postorderEnd - 1];
TreeNode* root = new TreeNode(rootValue);
if (postorderEnd - postorderBegin == 1) return root;
int delimiterIndex;
for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {
if (inorder[delimiterIndex] == rootValue) break;
}
// 切割中序数组
// 左中序区间,左闭右开[leftInorderBegin, leftInorderEnd)
int leftInorderBegin = inorderBegin;
int leftInorderEnd = delimiterIndex;
// 右中序区间,左闭右开[rightInorderBegin, rightInorderEnd)
int rightInorderBegin = delimiterIndex + 1;
int rightInorderEnd = inorderEnd;
// 切割后序数组
// 左后序区间,左闭右开[leftPostorderBegin, leftPostorderEnd)
int leftPostorderBegin = postorderBegin;
int leftPostorderEnd = postorderBegin + delimiterIndex - inorderBegin; // 终止位置是 需要加上 中序区间的大小size
// 右后序区间,左闭右开[rightPostorderBegin, rightPostorderEnd)
int rightPostorderBegin = postorderBegin + (delimiterIndex - inorderBegin);
int rightPostorderEnd = postorderEnd - 1; // 排除最后一个元素,已经作为节点了
root->left = traversal(inorder, leftInorderBegin, leftInorderEnd, postorder, leftPostorderBegin, leftPostorderEnd);
root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0)
return NULL;
return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size());
}
};
105.从前序与中序遍历序列构造二叉树
题目链接:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/
实现情况:
/**
* 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:
TreeNode* traversal(vector<int>& inorder, int inorderBrgin, int inorderEnd,
vector<int>& preorder, int preorderBegin,
int preorderEnd) {
if (preorderBegin == preorderEnd)
return NULL; //
// 获取根节点
int rootValue = preorder[preorderBegin];
TreeNode* root = new TreeNode(rootValue);
if (preorderEnd - preorderBegin == 1)
return root; // 前序,如果只有一个 那这个就是根节点
int delimiterIndex; // 在中序中找到根节点
for (delimiterIndex = inorderBrgin; delimiterIndex < inorderEnd;
delimiterIndex++) {
if (inorder[delimiterIndex] == rootValue)
break;
}
// 分割中序数组
// 中序左区间 [leftInorderBegin,leftInorderEnd);
int leftInorderBegin = inorderBrgin;
int leftInorderEnd = delimiterIndex;
//[rightInorderBegin, rightInorderEnd)
int rightInorderBegin = delimiterIndex + 1;
int rightInorderEnd = inorderEnd;
// 切割前序数组
//[leftPreorderBegin, leftPreorderEnd)
//delimiterIndex - inorderBrgin= 中序左区间的长度
int leftPreorderBegin = preorderBegin + 1;
int leftPreorderEnd = preorderBegin + 1 + delimiterIndex - inorderBrgin;
//[rightPreorderBegin, rightPreorderEnd)
int rightPreorderBegin =
preorderBegin + 1 + (delimiterIndex - inorderBrgin);
int rightPreorderEnd = preorderEnd;
root->left = traversal(inorder, leftInorderBegin, leftInorderEnd,
preorder, leftPreorderBegin, leftPreorderEnd);
root->right = traversal(inorder, rightInorderBegin, rightInorderEnd,
preorder, rightPreorderBegin, rightPreorderEnd);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (!inorder.size() || preorder.size() == 0)
return NULL;
return traversal(inorder, 0, inorder.size(), preorder, 0,
preorder.size());
}
};
总结
注意理解回溯的使用,牢记遍历的顺序和需求