112.路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
思路:代码量少一些,思路也清晰,根据递归三部曲走,首先判断终止条件,当 当前节点的左右节点不为空时,且目标值为当前值,(因为每次递归我都减去当前节点的值,所以到达叶子节点的时候,此时的值为当前节点的值)然后返回bool值给左右的布尔类型,返回值取||逻辑或,
如果其中至少有一个表达式为真(true),则整个逻辑表达式的结果为真(true);只有当所有表达式都为假(false)时,整个表达式才为假(false)。
class Solution {
public:
bool travelRoot(TreeNode* cur,int targetSum){
if(cur==nullptr){
return false;
}
if(cur->left==nullptr&&cur->right==nullptr&&targetSum==cur->val){
return true;
}
bool leftNum=travelRoot(cur->left,targetSum-cur->val);
bool rightNum=travelRoot(cur->right,targetSum-cur->val);
return leftNum||rightNum;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
return travelRoot(root,targetSum);
}
};
106.从中序遍历和后序遍历构造二叉树
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
思路:二叉树的后续遍历的最后一个节点就是当前要构造这个二叉树的根节点,在中序遍历中找出这个根节点,根节点的左右两边,就分别是左子树和右子树,定义一个动态数组代表左子树的中序遍历,在定义一个代表右子树的中序遍历,要注意将后序遍历的动态数组-1,因为后序数组的最后一个元素指定不能要了,这是切割点 也是 当前二叉树中间节点的元素,已经用了。
然后在定义两个后序的左右动态数组,通过后序的左右区间来去切割中序的左右区间,然后再用中序的左右区间去切割后序的左右区间,然后递归处理左右区间。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(postorder.size()==0){
return nullptr;
}
int size1=inorder.size();
int size2=postorder.size();
int index=0;
TreeNode* cur=new TreeNode(postorder[size2-1]);
for(int i=0;i<inorder.size();i++){
if(cur->val==inorder[i]){
index=i;
}
}
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> rightpostoder(postorder.begin()+leftinorder.size(),postorder.end());
cur->left=buildTree(leftinorder,leftpostorder);
cur->right=buildTree(rightinorder,rightpostoder);
return cur;
}
};
617.合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
思路:两个节点同时遍历,如果有一个节点为空,则返回另一个节点,因为要合并嘛,然后如果二者均不为空,将二者的和相加,返回给root1(或是root2),然后递归遍历,构造左右子树。
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==nullptr)
return root2;
if(root2==nullptr)
return root1;
root1->val+=root2->val;
root1->left=mergeTrees(root1->left,root2->left);
root1->right=mergeTrees(root1->right,root2->right);
return root1;
}
};
654.最大二叉树
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
思路:我感觉和106.从中序遍历和后序遍历构造二叉树挺像的,首先找出动态数组中的最大值,记录下标和他的值,将最大值构造成二叉树的根节点,定义左右动态数组,用来存储根节点的左右子树,递归构造。
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size()==0)
return nullptr;
int maxNum=0;
int index=0;
for(int i=0;i<nums.size();i++){
if(maxNum<nums[i]){
maxNum=nums[i];
index=i;
}
}
TreeNode* root=new TreeNode(maxNum);
vector<int> leftinpost(nums.begin(),nums.begin()+index);
vector<int> rightinpost(nums.begin()+index+1,nums.end());
root->left=constructMaximumBinaryTree(leftinpost);
root->right=constructMaximumBinaryTree(rightinpost);
return root;
}
};