513.找树左下角的值
就是找最下面的左叶子
使用层序遍历,因为层序遍历使用的时队列,所以头部的元素(i==0)是最左侧的
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int res=0;
queue<TreeNode*> que;
if(root!=nullptr){
que.push(root);
}
while(!que.empty()){
int size=que.size();
for(int i=0;i<size;i++){
TreeNode* node=que.front();
if(i==0) res=node->val;
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return res;
}
};
112. 路径总和
其实也是遍历
得走到目标节点的根节点(上一个节点)才能判断
递归:
递归结束条件:
走到叶子节点&&得到相应总值 返回ture。若走到叶子节点但没有得到相应总值 返回false。
若不是叶子节点,继续递归
递归过程:
首先减去根节点的左子树值,判断其左子树是否符合条件(即再次进入递归)符合条件 返回true
不符合条件 根节点的值恢复原样(就当没来过左子树)
右子树重复上述过程
class Solution {
public:
bool traversal(TreeNode* root, int count){
if(!root->left&&!root->right&&count==0) return true;
if(!root->left&&!root->right) 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==nullptr) return false;
//为什么是targetSum-root->val
//这里判断根节点
return traversal(root,targetSum-root->val);
}
};
非递归
就是遍历,遍历过程中记录路径之和
使用pair
class Solution {
public:
//注意pair的语法
bool hasPathSum(TreeNode* root, int targetSum) {
stack<pair<TreeNode*,int>> st;
if(root!=nullptr){
st.push(pair(root,root->val));
}
while(!st.empty()){
pair<TreeNode*,int> node=st.top();
st.pop();
if(!node.first->left&&!node.first->right&&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
递归法
将路径记录下来就行了
问题:
为什么写成private????
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void transfer(TreeNode* root, int sum){
if(!root->left&&!root->right&&sum==0){
result.push_back(path);
return;
}
if(!root->left&&!root->right) return ;
if(root->left){
path.push_back(root->left->val);
sum-=root->left->val;
transfer(root->left,sum);
path.pop_back();
sum+=root->left->val;
}
if(root->right){
path.push_back(root->right->val);
sum-=root->right->val;
transfer(root->right,sum);
path.pop_back();
sum+=root->right->val;
}
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
result.clear();
path.clear();
if(root==nullptr) return result;
path.push_back(root->val);
transfer(root,targetSum-root->val);
return result;
}
};
106. 从中序与后序遍历序列构造二叉树
后序遍历确定根节点,分割中序遍历
中序遍历找出左右子树的节点数,分割后序遍历
//9,3,15,20,7
//9,15,7,20,3
//依照postorder的最后一个数字分割inorder
//舍弃末尾元素
//9, 3, 15,20,7
//9, 15,7,20,
//依照刚刚分割好的
class Solution {
private:
TreeNode* transfer(vector<int>& inorder, vector<int>& postorder){
if(postorder.size()==0) return nullptr;
//后序遍历最后一个数
int num=postorder[postorder.size()-1];
TreeNode* root=new TreeNode(num);
postorder.pop_back();
//分割inorder
int inmid=0;
for(;inmid<inorder.size();inmid++){
if(inorder[inmid]==root->val) break;
}
vector<int> inorderLeft(inorder.begin(),inorder.begin()+inmid);
vector<int> inorderRight(inorder.begin()+inmid+1,inorder.end());
//分割postorder
vector<int> postorderLeft(postorder.begin(),postorder.begin()+inorderLeft.size());
vector<int> postorderRight(postorder.begin()+inorderLeft.size(),postorder.end());
root->left=transfer(inorderLeft,postorderLeft);
root->right=transfer(inorderRight,postorderRight);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0||postorder.size()==0) return nullptr;
return transfer(inorder,postorder);
}
};
105. 从前序与中序遍历序列构造二叉树
与上文同理
class Solution {
private:
TreeNode* transfer(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0) return nullptr;
TreeNode*root=new TreeNode(preorder[0]);
preorder.erase(preorder.begin());
//分割中序
int midroot=0;
for(;midroot<inorder.size();midroot++){
if(inorder[midroot]==root->val) break;
}
vector<int> inorderLeft(inorder.begin(),inorder.begin()+midroot);
vector<int> inorderRight(inorder.begin()+midroot+1,inorder.end());
//分割前序
vector<int> preorderLeft(preorder.begin(),preorder.begin()+inorderLeft.size());
vector<int> preorderRight(preorder.begin()+inorderLeft.size(),preorder.end());
root->left=transfer(preorderLeft,inorderLeft);
root->right=transfer(preorderRight,inorderRight);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0||inorder.size()==0) return nullptr;
return transfer(preorder,inorder);
}
};