513.找树左下角的值
迭代法:层序遍历
class Solution {
public:
//层序遍历
int findBottomLeftValue(TreeNode* root) {
if(root == NULL)return 0;
queue<TreeNode*>que;
que.push(root);
int result;
while(!que.empty()){
int size = que.size();
for(int i = 0; i < size; i++){
TreeNode* node;
node = que.front();
que.pop();
//记录最后一行的第一个元素
if(i == 0) result = node->val;
if(node->left != NULL) que.push(node->left);
if(node->right != NULL)que.push(node->right);
}
}
return result;
}
};
递归法:
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;
}
return; //结束函数的执行,返回函数调用点
}
if(node->left){
depth++;
traversal(node->left, depth);
depth--;
}
if(node->right){
depth++;
traversal(node->right, depth);
depth--; //结束函数的执行,返回函数调用点
}
return;
}
int findBottomLeftValue(TreeNode* root) {
if(root == NULL)return 0;
traversal(root, 1);
return result;
}
};
112. 路径总和
递归法:
class Solution {
public:
bool traversal(TreeNode* root, int count) {
if(root->left == NULL && root->right == NULL && count == 0) return true;
if(root->left == NULL && root->right == NULL)return false;
if(root->left){
count -= root->left->val;
if(traversal(root->left, count))return true;
count += root->left->val;
}
if(root->right){
count -= root->right->val;
if(traversal(root->right, count))return true;
count += root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum){
if(root == NULL)return false;
return traversal(root, targetSum - root->val);
}
};
迭代法:在迭代法中,要记录从根节点到当前节点路径的值的总和。
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr)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 == nullptr && node.first->right == nullptr && targetSum == node.second)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;
}
};
113.路径总和ii
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void traversal(TreeNode* node, int count){
if(node->left == nullptr && node->right == nullptr && count == 0){
result.push_back(path); //符合条件的路径放入result中
return;
}
if(node->left == nullptr && node->right == nullptr) return;
if(node->left){
path.push_back(node->left->val);
count -= node->left->val;
traversal(node->left, count);
count += node->left->val;
path.pop_back();
}
if(node->right){
path.push_back(node->right->val);
count -= node->right->val;
traversal(node->right, count);
count += node->right->val;
path.pop_back();
}
return;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
result.clear();
path.clear();
if(root == nullptr)return result;
path.push_back(root->val);
traversal(root, targetSum-root->val);
return result;
}
};
106.从中序与后序遍历序列构造二叉树
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);
//如果后序数字的大小为1,那么该二叉树就遍历结束
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);
}
};
105.从前序与中序遍历序列构造二叉树
class Solution {
public:
TreeNode* traversal(vector<int>& preorder, int preorderBegin, int preorderEnd, vector<int>& inorder, int inorderBegin,int inorderEnd){
if(preorderBegin == preorderEnd)return NULL;
//将前序数组中的第一个元素当做中间节点
int rootValue = preorder[preorderBegin];
TreeNode* root = new TreeNode(rootValue);
if(preorder.size() == 1)return root;
//在中序数组中,寻找中间节点作为分割点
int delimiterIndex;
for(delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++){
if(inorder[delimiterIndex] == rootValue)break;
}
//分割中序数组(左闭右开区间)
int leftInorderBegin = inorderBegin;
int leftInorderEnd = delimiterIndex;
int rightInorderBegin = delimiterIndex + 1;
int rightInorderEnd = inorderEnd;
//分割前序数组(左闭右开区间)
preorderBegin = preorderBegin + 1;
int leftPreorderBegin = preorderBegin;
int leftPreorderEnd = leftPreorderBegin + delimiterIndex - inorderBegin;
int rightPreorderBegin = leftPreorderBegin + delimiterIndex - inorderBegin;
int rightPreorderEnd = preorderEnd;
//遍历
root->left = traversal(preorder, leftPreorderBegin, leftPreorderEnd, inorder, leftInorderBegin, leftInorderEnd);
root->right = traversal(preorder, rightPreorderBegin, rightPreorderEnd, inorder, rightInorderBegin, rightInorderEnd);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(inorder.size() == 0 || preorder.size() == 0)return NULL;
//左闭右开原则
return traversal(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
};