513. 找树左下角的值 - 力扣(LeetCode)
给定一个二叉树的 根节点
root,请找出该二叉树的 最底层 最左边 节点的值。假设二叉树中至少有一个节点。
自己AC的方法,逻辑比较混乱
class Solution {
private:
int maxdepth;
int curdepth = 1;//当前深度
int res;
int flag = 0;
public:
int findBottomLeftValue(TreeNode* root) {
maxdepth = gethigh(root);
traverse(root);
return res;
}
void traverse(TreeNode* node){
if(flag==1) return;
if(node == nullptr) return;
if(!node->left&&!node->right&&curdepth == maxdepth){
res = node->val;
flag = 1;
}
if(node->left){
curdepth++;
if(curdepth == maxdepth){
res = node->left->val;
curdepth--;
flag = 1;
return;
}
traverse(node->left);
curdepth--;
}
if(node->right){
curdepth++;
if(curdepth == maxdepth){
res = node->right->val;
curdepth--;
flag = 1;
return;
}
traverse(node->right);
curdepth--;
}
}
int gethigh(TreeNode* node){
if(node == nullptr) return 0;
int L = gethigh(node->left);
int R = gethigh(node->right);
return max(L,R)+1;
}
};
路径求和问题
把+/-融入递归/回溯的过程,复杂度为
找到路径后for循环累加,复杂度为
112. 路径总和 - 力扣(LeetCode)
给你二叉树的根节点
root和一个表示目标和的整数targetSum。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum。如果存在,返回true;否则,返回false。叶子节点 是指没有子节点的节点。
自己AC啦
class Solution {
private:
vector<int> path;
bool res;
public:
bool hasPathSum(TreeNode* root, int targetSum) {
traverse(root,targetSum);
return res;
}
void traverse(TreeNode* node,int targetSum){
if(res==1) return;
if(node == nullptr) return;
path.push_back(node->val);
if(!node->left&&!node->right){//遇到叶子节点判断和是否为tar
int sum = 0;
for(int i:path){
sum+=i;
}
if(sum==targetSum) res =1;
}
if(node->left){
traverse(node->left,targetSum);
path.pop_back();
}
if(node->right){
traverse(node->right,targetSum);
path.pop_back();
}
}
};
113. 路径总和 II - 力扣(LeetCode)
给你二叉树的根节点
root和一个整数目标和targetSum,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。
class Solution {
private:
vector<int> path;
vector<vector<int>> allpath;
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
traverse(root,targetSum);
return allpath;
}
void traverse(TreeNode* node,int targetSum){
if(node == nullptr) return;
path.push_back(node->val);
if(!node->left&&!node->right){//遇到叶子节点判断和是否为tar
int sum = 0;
for(int i:path){
sum+=i;
}
if(sum==targetSum){
allpath.push_back(path);
}
}
if(node->left){
traverse(node->left,targetSum);
path.pop_back();
}
if(node->right){
traverse(node->right,targetSum);
path.pop_back();
}
}
};
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
给定两个整数数组
inorder和postorder,其中inorder是二叉树的中序遍历,postorder是同一棵树的后序遍历,请你构造并返回这颗二叉树 。
分解问题思想。根据给的数组创立根节点,并拆分数组,再用拆分后的数组调用buildTree函数创立左子树、右子树并接在根节点下。最后返回根节点即可。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
vector<int>sub1_in;
vector<int>sub2_in;
vector<int>sub1_post;
vector<int>sub2_post;
if(postorder.empty()) return nullptr;
int mid = postorder.back();//后序的back是根节点
postorder.pop_back();
TreeNode* root = new TreeNode(mid);
//根据mid拆中序
for(int i = 0;i<inorder.size();i++){
if(inorder[i]==mid){ //找到分割位置
//i不在数组第一个,存在左子树
if(i!=0) copy(inorder.begin(),inorder.begin()+i,back_inserter(sub1_in));
//i不在数组最后一个,存在右子树
if(i!=inorder.size()-1) copy(inorder.begin()+(i+1),inorder.end(),back_inserter(sub2_in));
}
}
//根据拆出来的中序大小,拆后序
if(!sub1_in.empty()){ //sub1_in非空,有左子树
int size = sub1_in.size();
copy(postorder.begin(),postorder.begin()+size,back_inserter(sub1_post));
}
root->left = buildTree(sub1_in,sub1_post);
if(!sub2_in.empty()){ //sub2_in非空,有右子树
int size = sub2_in.size();
copy(postorder.end()-size,postorder.end(),back_inserter(sub2_post));
}
root->right = buildTree(sub2_in,sub2_post);
return root;
}
};