代码随想录算法训练营第二十一天
513.找树左下角的值
题目链接:513.找树左下角的值
层序遍历找每层的第一个值。递归找叶子节点记录其深度,如果比先前记录的最大深度大就更新最大深度,同时获取该节点的值。先遍历左节点记录该值,遍历右节点时,深度与左节点相同所以不会更新结果和最大深度。
// 方法1:层序遍历法
/**
* 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 findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if (!root)
return 0;
que.push(root);
int result;
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
auto cur = que.front();
que.pop();
if(i==0)result = cur->val;
if (cur->left)
que.push(cur->left);
if (cur->right)
que.push(cur->right);
}
}
return result;
}
};
//方法二:递归遍历
class Solution {
public:
int depth_max = -1;
int result;
void find(TreeNode* root,int depth){
if(root->left==nullptr&&root->right == nullptr){
if(depth>depth_max){
depth_max = depth;
result = root->val;
}
else return;
}
depth++;//中
if(root->left)find(root->left, depth);//左
if(root->right)find(root->right, depth);//右
return;
}
int findBottomLeftValue(TreeNode* root) {
find(root, 0);
return result;
}
};
112. 路径总和
题目链接:112. 路径总和
//方法一:求所有根节点到叶子节点的和,再遍历结果集,如果结果集内有,目标和就返回true
class Solution {
public:
void getSum(TreeNode* root,int &sum,vector<int> &res){
if(!root)return ;
if(root->left==nullptr&&root->right==nullptr){
sum+=root->val;
res.push_back(sum);
return;
};
sum+=root->val;
if(root->left){
getSum(root->left, sum,res);
sum-=root->left->val;//引用传递,手动回溯。
};
if(root->right){
getSum(root->right, sum,res);
sum-=root->right->val;//引用传递,手动回溯。
};
}
bool hasPathSum(TreeNode* root, int targetSum) {
int sum = 0;
vector<int> res;
getSum(root, sum,res);
for(auto &num:res){
if(num == targetSum)return true;
}
return false;
}
};
//方法二
class Solution {
public:
bool getSum(TreeNode* root,int &sum){
bool result =false;
if(!root)return false;
if(root->left==nullptr&&root->right==nullptr){
sum-=root->val;
if(sum==0)result=true;
else result= false;
return result;
};
sum-=root->val;
if(root->left&&!result){
result =getSum(root->left, sum);
sum+=root->left->val;
};
if(root->right&&!result){
result = getSum(root->right, sum);
sum+=root->right->val;//引用传递,手动回溯。
};
return result;
}
bool hasPathSum(TreeNode* root, int targetSum) {
return getSum(root, targetSum);
}
};
113.路径总和ii
题目链接:113.路径总和ii
/**
* 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:
void getSum(TreeNode* root, int sum, vector<int> result,
vector<vector<int>>& results) {
if (!root)
return;
sum -= root->val;
result.push_back(root->val);
if (root->left == nullptr && root->right == nullptr) {
if (sum == 0)
results.push_back(result);
};
if (root->left) {
getSum(root->left, sum, result,results);
// sum += root->left->val; //如果传引用就要手动回溯,传值则不用
// result.pop_back();
};
if (root->right) {
getSum(root->right, sum,result,results);
// sum += root->right->val;
// result.pop_back();
};
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<vector<int>> results;
vector<int> result;
getSum(root, targetSum, result, results);
return results;
}
};
106.从中序与后序遍历序列构造二叉树
题目链接:106.从中序与后序遍历序列构造二叉树
后序遍历,后续数组最后一个节点就是根节点,通过根节点在中序数组中的位置,切分左子树和右子树,在根据中序数组中左子树节点的个数在后序数组中前面计数左子树节点个数,剩下就是右节点个数和根节点。
/**
* 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(!inorder.size())return nullptr; // 空列表直接返回。
int rootVal = postorder[postorder.size()-1];//
TreeNode* root = new TreeNode(rootVal);
if(inorder.size() == 1)return root;
int root_index = 0;
for(;root_index<inorder.size();root_index++){
if(inorder[root_index]==rootVal)break;
}
vector<int> left_son_inorder,
right_son_inorder,
left_son_postorder,
right_son_postorder;
for(int i = 0;i<root_index;i++){
left_son_inorder.push_back(inorder[i]);
left_son_postorder.push_back(postorder[i]);
}
for(int i = root_index+1;i<inorder.size();i++){
right_son_inorder.push_back(inorder[i]);//
right_son_postorder.push_back(postorder[i-1]);
}
root->left = buildTree(left_son_inorder, left_son_postorder);
root->right = buildTree(right_son_inorder, right_son_postorder);
return root;
}
};
105.从前序与中序遍历序列构造二叉树
题目链接:105.从前序与中序遍历序列构造二叉树
前序遍历,前序数组第一个节点就是根节点,通过根节点在中序数组中的位置,切分左子树和右子树,在根据中序数组中左子树节点的个数在前序数组中根节点后面计数左子树节点个数,剩下就是右节点个数。
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(!preorder.size())return nullptr;
int rootVal = preorder[0];
TreeNode* root = new TreeNode(rootVal);
int rootIndex = 0;
for(;rootIndex<inorder.size();rootIndex++){
if(inorder[rootIndex]==rootVal)break;
}
vector<int> son_left_preorder(preorder.begin()+1,preorder.begin()+rootIndex+1);
vector<int> son_right_preorder(preorder.begin()+rootIndex+1,preorder.end());
vector<int> son_left_inorder(inorder.begin(),inorder.begin()+rootIndex);
vector<int> son_right_inorder(inorder.begin()+rootIndex+1,inorder.end());
root->left = buildTree(son_left_preorder, son_left_inorder);
root->right = buildTree(son_right_preorder, son_right_inorder);
return root;
}
};