404.左叶子之和
思路:
求出左叶子之和的关键在求叶子结点的条件,并且这是左叶子节点,但是在当前节点的时候无法确定自己是不是左叶子结点,所以求左叶子结点,一定要通过操作该结点的父节点。
513.找树左下角的值
给定一个二叉树,在树的最后一行找到最左边的值。
注意点是这个最左边的值不一定是左孩子的值,还可能是右孩子的值
思路:
使用迭代法,层序遍历很简单。
递归法也可以,递归法使用前中后序遍历都可以,关键点在于先访问左子节点,再访问右子节点,求深度,深度最大一层的最先访问到的节点就是树最底层最左边的节点。
代码展示
/**
* 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_MIN;
int result;//result用于统计最深层的叶子最左边的叶子结点
void traversal(TreeNode* node,int depth){
//递归终止条件 当遇到叶子结点的时候,比较是不是最大深度
if(node->left==nullptr&&node->right==nullptr){
if(depth>maxDepth){
//如果深度大于最大深度
maxDepth=depth;
result=node->val;
}
return ;
}
if(node->left){
depth++;
traversal(node->left,depth);
depth--;
}
if(node->right){
depth++;
traversal(node->right,depth);
depth--;
}
return ;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,1);
return result;
//递归求左下角节点
}
};
112. 路径总和
思路:对二叉树运用前序遍历,用一个count(count=count-当前节点的值)作为计数器,一直遍历到叶子结点,如果遍历到当前叶子结点时计数器count=0,遍历结束,return true.如果计数器count!=0,那么就向上回溯,返回上一个结点,并且将count也返回上一个节点时候的值,
注意: 这里不需要遍历完整个二叉树,只需要遍历到满足条件的路径就可以了,所以递归函数需要返回值,作为停止遍历的标志,当遇到return true,递归操作停止。
/**
* 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* cur, int count) {
if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
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;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==nullptr) return false;
return traversal(root,targetSum-root->val);
}
};
106.从中序与后序遍历序列构造二叉树
思路:
1.如果后序数组的大小等于0时,return null
2.将后序数组的最后一个元素取出,判断如果后续数组只有一个元素就return 取出的元素。
3.用后序数组取出的元素,遍历中序数组,找到切割点位置
4.将中序数组进行切割
5.用中序数组将后序数组进行切割
6.递归进行创建相应的左右子树的操作
/**
* 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 nullptr;
int rootValue=postorder[postorder.size()-1];
TreeNode *root=new TreeNode(rootValue);
if(postorder.size()==1)
return root;
int index=0;
for(index=0;index<postorder.size();index++){
if(inorder[index]==rootValue) 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());
//进行递归遍历
root->left=buildTree(leftInOrder,leftPostorder);
root->right=buildTree(rightInOrder,rightPostorder);
return root;
}
};