Leetcode 112. 路径总和
思路:哪种遍历顺序都可以,题目不涉及中节点的处理,使用计数器cnt
,初始时cnt
等于目标节点的值,每次遍历到一个新的节点就减去当前节点的值,如果遍历到叶子节点时cnt==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* node, int cnt){ //cnt用来判断是否找到目标路径
if(node->left==NULL && node->right==NULL && cnt==0)return true; //遍历到叶子节点并且路径所有值相加等于目标和
if(node->left==NULL && node->right==NULL)return false;
if(node->left){
cnt-=node->left->val; //左
if(traversal(node->left, cnt))return true;
cnt+=node->left->val; //回溯
}
if(node->right){
cnt-=node->right->val; //右
if(traversal(node->right, cnt))return true;
cnt+=node->right->val; //回溯
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL)return false;
return traversal(root, targetSum-root->val);
}
};
Leetcode 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 reuslt; //最底层最左边的值
void traversal(TreeNode* node, int depth){
if(node->left==NULL && node->right==NULL){
if(depth > maxDepth){
maxDepth = depth; //更新最大深度
reuslt = 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, 0);
return reuslt;
}
};
Leetcode 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* traversal(vector<int> &inorder, vector<int> &postorder){
if(postorder.size()==0)return NULL;
int rootValue = postorder[postorder.size()-1]; //后序数组的最后一个元素
TreeNode* root = new TreeNode(rootValue);
if(postorder.size()==1)return root; //遇到叶子节点
int delimiterIndex; //切割点索引
for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++){
if(inorder[delimiterIndex]==rootValue)break; //找到切割点
}
vector<int> leftInorder(inorder.begin(),inorder.begin()+delimiterIndex); //左中序数组
vector<int> rightInorder(inorder.begin()+delimiterIndex+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 = traversal(leftInorder,leftPostorder);
root->right = traversal(rightInorder, rightPostorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0 || postorder.size()==0)return NULL;
return traversal(inorder, postorder);
}
};