513. 找树左下角的值
给定一个二叉树的根节点 root,请找出该二叉树的最底层最左边节点的值。
假设二叉树中至少有一个节点。
解:
使用迭代法:
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
//用层序遍历法(迭代法)
int result=0;
queue<TreeNode*> que;
if(root != NULL) que.push(root);
while(!que.empty())
{
vector<int> vec;
int size = que.size();
while(size--)
{
TreeNode* cur = que.front();
que.pop();
vec.push_back(cur->val);
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
}
result=vec[0];
}
return result;
}
};
使用递归法:
class Solution {
public:
int maxDepth = INT_MIN;
int result;
void traversal(TreeNode* root, int depth) {
if (root->left == NULL && root->right == NULL) {
if (depth > maxDepth) {
maxDepth = depth;
result = root->val;
}
return;
}
if (root->left) {
depth++;
traversal(root->left, depth);
depth--; // 回溯
}
if (root->right) {
depth++;
traversal(root->right, depth);
depth--; // 回溯
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root, 0);
return result;
}
};
112. 路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
解:
class Solution {
private:
void traversal(TreeNode* cur,vector<int>& path,vector<int>& result)
{
//用前序遍历
path.push_back(cur->val);
if(cur->left == NULL && cur->right == NULL)
{
int sum=0;
for(int i=0;i<path.size();i++)
{
sum += path[i];
}
result.push_back(sum);
}
//左遍历
if(cur->left)
{
traversal(cur->left,path,result);
path.pop_back();
}
if(cur->right)
{
traversal(cur->right,path,result);
path.pop_back();
}
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL) return false;
vector<int> path;
vector<int> result;
traversal(root,path,result);
for(int i=0;i<result.size();i++)
{
if(targetSum==result[i]) return true;
}
return false;
}
};
113. 路径总和 II
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
解:
class Solution {
private:
void traversal(TreeNode* cur,vector<int>& path,vector<int>& result,vector<vector<int>>& path_)
{
//用前序遍历
path.push_back(cur->val);
if(cur->left == NULL && cur->right == NULL)
{
int sum=0;
for(int i=0;i<path.size();i++)
{
sum += path[i];
}
result.push_back(sum);
path_.push_back(path);
}
//左遍历
if(cur->left)
{
traversal(cur->left,path,result,path_);
path.pop_back();
}
if(cur->right)
{
traversal(cur->right,path,result,path_);
path.pop_back();
}
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> path;
vector<vector<int>> path_;
vector<vector<int>> result_;
vector<int> result;
if(root == NULL) return result_;
traversal(root,path,result,path_);
for(int i=0;i<result.size();i++)
{
if(targetSum==result[i])
result_.push_back(path_[i]);
}
return result_;
}
};
106. 从中序与后序遍历序列构造二叉树
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
解:
class Solution {
private:
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 index;
for(index=0;index<inorder.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=traversal(leftinorder,leftpostorder);
root->right=traversal(rightinorder,rightpostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return NULL;
return traversal(inorder, postorder);
}
};
105. 从前序与中序遍历序列构造二叉树
解:
class Solution {
private:
TreeNode* traversal (vector<int>& inorder, int inorderBegin, int inorderEnd, vector<int>& preorder, int preorderBegin, int preorderEnd) {
if (preorderBegin == preorderEnd) return NULL;
int rootValue = preorder[preorderBegin]; // 注意用preorderBegin 不要用0
TreeNode* root = new TreeNode(rootValue);
if (preorderEnd - preorderBegin == 1) return root;
int delimiterIndex;
for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {
if (inorder[delimiterIndex] == rootValue) break;
}
// 切割中序数组
// 中序左区间,左闭右开[leftInorderBegin, leftInorderEnd)
int leftInorderBegin = inorderBegin;
int leftInorderEnd = delimiterIndex;
// 中序右区间,左闭右开[rightInorderBegin, rightInorderEnd)
int rightInorderBegin = delimiterIndex + 1;
int rightInorderEnd = inorderEnd;
// 切割前序数组
// 前序左区间,左闭右开[leftPreorderBegin, leftPreorderEnd)
int leftPreorderBegin = preorderBegin + 1;
int leftPreorderEnd = preorderBegin + 1 + delimiterIndex - inorderBegin; // 终止位置是起始位置加上中序左区间的大小size
// 前序右区间, 左闭右开[rightPreorderBegin, rightPreorderEnd)
int rightPreorderBegin = preorderBegin + 1 + (delimiterIndex - inorderBegin);
int rightPreorderEnd = preorderEnd;
root->left = traversal(inorder, leftInorderBegin, leftInorderEnd, preorder, leftPreorderBegin, leftPreorderEnd);
root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, preorder, rightPreorderBegin, rightPreorderEnd);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (inorder.size() == 0 || preorder.size() == 0) return NULL;
// 参数坚持左闭右开的原则
return traversal(inorder, 0, inorder.size(), preorder, 0, preorder.size());
}
};