513.找树左下角的值
给定一个二叉树,在树的最后一行找到最左边的值。
这题用层序遍历简单,直接遍历到最后一层的第一个值即可,可以用一个flag标记每层的最左边的值。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> qu;
int size=0;
int res=0;
int flag=0;
if(root==NULL)return 0;
qu.push(root);
while(!qu.empty())
{
size=qu.size();
flag=0;
while(size--)
{ auto node=qu.front();
qu.pop();
if(flag==0)
{
res=node->val;
flag=1;
}
if(node->left)qu.push(node->left);
if(node->right)qu.push(node->right);
}
}
return res;
}
};
至于递归,有点困难,需要使用递归+回溯的组合来得到最下面的值,而遍历顺序其实无所谓,因为我们不对中间结点作处理,只要保证左->右即可,这样到最后一层,自然会保证是最左边的值:
class Solution {
public:
int maxdepth=INT32_MIN;
int res;
int traversal(TreeNode* root,int depth)
{
if(root->left==NULL&&root->right==NULL)
{
if(depth>maxdepth)
{
maxdepth=depth;
res=root->val;
}
return res;
}
if(root->left)
{depth++;
traversal(root->left,depth);
depth--;
}
if(root->right)
{
depth++;
traversal(root->right,depth);
depth--;
}
return res;
}
int findBottomLeftValue(TreeNode* root) {
return traversal(root,0);
}
};
112. 路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例: 给定如下二叉树,以及目标和 sum = 22,
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
这题迭代可以用栈来模拟前序遍历,然后另外一个栈放路径总和就行。
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
stack<TreeNode* > treest;
stack<int> sumst;
if(root==NULL)return 0;
treest.push(root);
sumst.push(root->val);
while(!treest.empty())
{
auto node=treest.top();treest.pop();
int sum=sumst.top();sumst.pop();
if(node->left==NULL&&node->right==NULL)
{
if(sum==targetSum)return 1;
}
if(node->right)
{
treest.push(node->right);
sumst.push(sum+node->right->val);
}
if(node->left)
{
treest.push(node->left);
sumst.push(sum+node->left->val);
}
}
return 0;
}
};
至于递归的话,需要注意找到了一直返回就行,还需要对sum进行回溯,然后虽然说不对中间结点进行处理,但是一开始的时候要注意加上中间结点
class Solution {
public:
bool pathsum(TreeNode* root,int target,int sum)
{ //if(root==NULL) return 0;
//sum+=root->val;
if(root->left==NULL&&root->right==NULL)
{
if(sum==target)
{
return 1;
}
else
return 0;
}
if(root->left)
{
//sum+=root->left->val;
if(pathsum(root->left,target,sum+root->left->val))return 1;
//sum-=root->left->val;
}
if(root->right)
{
//sum+=root->right->val;
if(pathsum(root->right,target,sum+root->right->val))return 1;
//sum-=root->right->val;
}
return 0;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if (root == NULL) return false;
return pathsum(root,targetSum,root->val);
}
};
给你二叉树的根节点 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]]
这题迭代法的话,需要用3个栈:
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
stack<TreeNode* > treest;
stack<int> sumst;
stack<vector<int>> pathst;
vector<vector<int>> result;
if(root==NULL)return {};
vector<int> temp;
temp.push_back(root->val);
treest.push(root);
sumst.push(root->val);
pathst.push(temp);
while(!treest.empty())
{
auto node=treest.top();treest.pop();
int sum=sumst.top();sumst.pop();
vector<int> res=pathst.top();pathst.pop();
if(node->left==NULL&&node->right==NULL)
{
if(sum==targetSum)
{
result.push_back(res);
}
}
if(node->right)
{
treest.push(node->right);
sumst.push(sum+node->right->val);
res.push_back(node->right->val);
pathst.push(res);
res.pop_back();
}
if(node->left)
{
treest.push(node->left);
sumst.push(sum+node->left->val);
res.push_back(node->left->val);
pathst.push(res);
res.pop_back();
}
}
return result;
}
};
递归跟之前也差不多,需要注意多一个数组放路径即可,并且需要回溯:
/**
* 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:
void path(TreeNode* root,int target,int sum,vector<int>& res,vector<vector<int>>& result)
{ if(root->left==NULL&&root->right==NULL)
{
if(sum==target)result.push_back(res);
}
if(root->left)
{
sum+=root->left->val;
res.push_back(root->left->val);
path(root->left,target,sum,res,result);
sum-=root->left->val;
res.pop_back();
}
if(root->right)
{
sum+=root->right->val;
res.push_back(root->right->val);
path(root->right,target,sum,res,result);
sum-=root->right->val;
res.pop_back();
}
// return result;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(root==NULL)return {};
vector<int> res;
vector<vector<int>> result;
res.push_back(root->val);
int sum=root->val;
path(root,targetSum,sum,res,result);
return result;
}
};
106.从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
- 中序遍历 inorder = [9,3,15,20,7]
- 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:
妙呀,建议看视频:
坑很多!来看看你掉过几次坑 | LeetCode:106.从中序与后序遍历序列构造二叉树_哔哩哔哩_bilibili
class Solution {
public:
TreeNode* traversal(vector<int>& inorder,vector<int>& postorder)
{
if(postorder.size()==0)return nullptr;
int rootval=postorder[postorder.size()-1];
auto root=new TreeNode(rootval);
if(postorder.size()==1)return root;
int index=0;
for(index=0;index<inorder.size();index++)
{
if(inorder[index]==rootval)break;
}
vector<int> leftin;vector<int> rightin;
vector<int> leftpost;vector<int> rightpost;
for(int i=0; i<index;i++)//左中序
leftin.push_back(inorder[i]);
for(int i=index+1; i<inorder.size();i++)//右中序
rightin.push_back(inorder[i]);
for(int i=0;i<leftin.size();i++)//左后序
leftpost.push_back(postorder[i]);
for(int i=leftin.size();i<postorder.size()-1;i++)//右后序
rightpost.push_back(postorder[i]);
//for(int i=0;i<rightin.size();i++)//右后序
//rightpost.push_back(postorder[i+leftin.size()]);
root->left=traversal(leftin,leftpost);
root->right=traversal(rightin,rightpost);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return traversal(inorder,postorder);
}
};
这是前序和中序的:
/**
* 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 rootval=preorder[0];
auto root=new TreeNode(rootval);
if(preorder.size()==1)return root;
int index=0;
for(index=0;index<inorder.size();index++)//中序遍历位置
if(inorder[index]==rootval)break;
vector<int> leftpre;vector<int> rightpre;//左前,右前
vector<int> leftin;vector<int> rightin;//左中,右中
for(int i=0;i<index;i++)
leftin.push_back(inorder[i]);
for(int i=index+1;i<inorder.size();i++)
rightin.push_back(inorder[i]);
for(int i=1;i<1+leftin.size();i++) //左前
leftpre.push_back(preorder[i]);
for(int i=1+leftin.size();i<preorder.size();i++) //右前
rightpre.push_back(preorder[i]);
root->left=traversal(leftpre,leftin);
root->right=traversal(rightpre,rightin);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return traversal(preorder,inorder);
}
};
递归真难