左叶子之和 找左下角的值 路径总和
1.计算给定二叉树的所有左叶子之和。
#include <bits/stdc++.h>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x)
{
val=x;
left=NULL;
right=NULL;
}
};
int findsum(TreeNode* root)
{
if(root==NULL)
return 0;
if(root->left==NULL&&root->right==NULL)
return 0;
int leftnum=findsum(root->left);
if(root->left&&!root->left->left&&!root->left->right)
{
leftnum=root->left->val;
}
int rightnum=findsum(root->right);
int sum=leftnum+rightnum;
return sum;
}
int main()
{
TreeNode* root=new TreeNode(1);
root->left=new TreeNode(2);
root->right=new TreeNode(3);
root->left->left=new TreeNode(4);
root->left->right=new TreeNode(6);
root->left->right->right=new TreeNode(7);
root->right->left=new TreeNode(5);
int sum=findsum(root);
cout<<sum;
return 0;
}
思路:首先我们要搞清楚左叶子,即左右子树的左侧叶子结点,特征就是没有左右孩子,且在父结点的左侧,另外在判断左叶子时我们只能借助于父结点,因为在遍历到叶子结点时我们无法判断其是左叶子还是右叶子,在这里我们就用到后序遍历,通过递归函数的返回值来累加求取左叶子数值之和。
当结点为空时,左叶子一定是0,当为叶子结点时左叶子也是0,只有当遍历到父结点且其含有左叶子时,返回其值。
2.给定一个二叉树,在树的最后一行找到最左边的值。
#include <bits/stdc++.h>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x)
{
val=x;
left=NULL;
right=NULL;
}
};
int findValue(TreeNode* root)
{
queue<TreeNode*> que;
int result=0;
if(root!=NULL)
{
que.push(root);
}
while(!que.empty())
{
int size=que.size();
for(int i=0;i<que.size();i++)
{
TreeNode* node=que.front();
que.pop();
if(i==0)
result=node->val;
if(node->left)
que.push(node->left);
if(node->right)
que.push(node->right);
}
}
return result;
}
int main()
{
TreeNode* root=new TreeNode(1);
root->left=new TreeNode(2);
root->right=new TreeNode(3);
root->left->left=new TreeNode(4);
root->left->right=new TreeNode(6);
root->left->right->right=new TreeNode(7);
root->right->left=new TreeNode(5);
cout<<findValue(root);
return 0;
}
思路:这道题的左下角的值我们要知道指的是深度最大的那一行的最左侧的值,那么其实不找深度最大的一行的第一个元素就行了,因而层序遍历显得比较适合。
层序遍历之前已经提到过就不多赘述了,就只是在此基础上修改了一小部分,就是取每一层的第一个元素给result,会逐层覆盖,最终输出的就是最后一层的第一个元素了。
3.给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
#include <bits/stdc++.h>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x)
{
val=x;
left=NULL;
right=NULL;
}
};
bool isGoal(TreeNode* root,int target)
{
if(root->left==NULL&&root->right==NULL&&target==0)
return true;
if(root->left==NULL&&root->right==NULL&&target!=0)
return false;
if(root->left)
{
target-=root->left->val;
if(isGoal(root->left,target))
return true;
target+=root->left->val;
}
if(root->right)
{
target-=root->right->val;
if(isGoal(root->right,target))
return true;
target+=root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root,int sum)
{
if(root==NULL)
return false;
return isGoal(root,sum-root->val);
}
int main()
{
TreeNode* root=new TreeNode(1);
root->left=new TreeNode(2);
root->right=new TreeNode(3);
root->left->left=new TreeNode(7);
root->left->right=new TreeNode(5);
cout<<((hasPathSum(root,10)==1)?"true":"false");
return 0;
}
思路:这里我们可以这样想,开始遍历时,将目标值target传入,如果存在根节点就先用target减去其val值,先遍历左子树,此时遍历到根节点时减去其左子树的值,之后每遍历一个左节点就继续减去它的左子树的值,直到叶子节点时,如果此时target为0,那么就说明存有路径和为target,返回true,否则就进行回溯,将target回复原来的值转而向另外的路径探索看是否存有这样的路径,遍历右子树也是如此,注意这里我们如果找到了符合的路径,但仍未遍历完整棵树,也是直接返回true,不必继续遍历。