1.找到左下角的值
513. 找树左下角的值 - 力扣(LeetCode)
代码随想录 (programmercarl.com)
代码:
class Solution {
public:
int maxDepth = INT_MIN;
int result;
// 深度最大,确保是最后一行 先遍历左孩子再遍历右孩子 确保是左下角
void traversal(TreeNode* node,int Depth){
if(node->left == NULL && node->right == NULL){
if(Depth > maxDepth){
maxDepth = Depth;
result = node->val;
}
}
if(node->left){
Depth++;
traversal(node->left,Depth);
Depth--;
}
if(node->right){
Depth++;
traversal(node->right,Depth);
Depth--;
}
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return result;
}
};
note:深度最大,确保是最后一行 先遍历左孩子再遍历右孩子 确保是左下角
2.路径总和
112. 路径总和 - 力扣(LeetCode)
代码随想录 (programmercarl.com)
代码:(递归法)
class Solution {
public:
bool traversal(TreeNode* node,int sum){
if(node == NULL) return false;
if(node->left == NULL && node->right == NULL && sum == node->val){
return true;
}
// 左
bool left = traversal(node->left,sum - node->val);
// 右
bool right = traversal(node->right,sum - node->val);
return left || right;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == NULL) return false;
return traversal(root,targetSum);
}
};
note:这里需要注意的点是,要自己确定好自己的递归函数里的参数sum变量是减了当前节点val值呢,还是没有减要在本次函数里操作的。这个就决定了你的终止条件怎么写。
以及,这里的判断是,左右孩子只要有一个满足题意的叶子结点,就算true了!!
代码:(迭代法)
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == NULL) return false;
stack<pair<TreeNode*,int>> st;
st.push(pair<TreeNode*,int>(root,root->val));
while(!st.empty()){
pair<TreeNode*,int> node = st.top();
st.pop();
if(!node.first->left && !node.first->right && node.second == targetSum){
return true;
}
// 右
if(node.first->right){
st.push(pair<TreeNode*,int>(node.first->right,node.second + node.first->right->val));
}
// 左
if(node.first->left){
st.push(pair<TreeNode*,int>(node.first->left,node.second + node.first->left->val));
}
}
return false;
}
};
note:这里用一个二元组来记录每个结点,以及其对应的路径总和
相关题目练习
113. 路径总和 II - 力扣(LeetCode)
代码:递归法
class Solution {
public:
vector<vector<int>> result;
void traversal(TreeNode* node,int sum,vector<int> &path){
if(node == NULL) return;
if(!node->left && !node->right && node->val == sum){
path.push_back(node->val);
result.push_back(path);
path.pop_back();
return;
}
if(node->left){
path.push_back(node->val);
traversal(node->left,sum - node->val,path);
path.pop_back();
}
if(node->right){
path.push_back(node->val);
traversal(node->right,sum - node->val,path);
path.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> path;
traversal(root,targetSum,path);
return result;
}
};
note:要遍历整颗树的时候 不需要返回值;不需要遍历整颗树的,需要返回值及时退出递归
3.从中序与后序遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
题目链接/文章讲解/视频讲解:代码随想录
代码:
/**
* 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);
}
};
note:
相关题目练习
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
代码:
/**
* 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>& preorder,vector<int>& inorder){
if(preorder.size() == 0) return NULL;
// 找到根结点
int rootValue = preorder[0];
TreeNode* root = new TreeNode(rootValue);
// 叶子结点
if(preorder.size() == 1){
return root;
}
// 找到切割点
int delimitIndex;
for(delimitIndex = 0; delimitIndex < inorder.size(); delimitIndex++){
if(inorder[delimitIndex] == rootValue){
break;
}
}
// 切割中序遍历数组
vector<int> leftInoreder(inorder.begin(),inorder.begin() + delimitIndex);
vector<int> rightInorder(inorder.begin() + delimitIndex + 1,inorder.end());
// 切割前序遍历数组
vector<int> leftPreorder(preorder.begin() + 1,preorder.begin() + 1 + leftInoreder.size());
vector<int> rightPreorder(preorder.begin() + 1 + leftInoreder.size(),preorder.end());
//
root->left = traversal(leftPreorder,leftInoreder);
root->right = traversal(rightPreorder,rightInorder);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0 || inorder.size() == 0){
return NULL;
}
return traversal(preorder,inorder);
}
};