513.找树左下角的值
这样的是递归的写法。在递归写法中我们一定要注意回溯,保证在遍历右子树的时候我们的depth的值没有改变。其实在栈低的每一个函数体内部都会有这样一个过程,所以我们每次只用回溯1。
class Solution {
public:
int result;
int maxdepth=-1;
void traversal(TreeNode *node,int depth)
{
if(node->left==nullptr&&node->right==nullptr)
{
if(depth>maxdepth)
{
maxdepth=depth;
result=node->val;
}
return;
}
if(node->left)
{
depth++;
traversal(node->left,depth);
depth--;
}
if(node->right)
{
depth++;
traversal(node->right,depth);
depth--;
}
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return result;
}
};
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int result;
queue<TreeNode*> que;
if(root!=nullptr)
que.push(root);
int size=1;
while(!que.empty())
{
size=que.size();
for(int i=0;i<size;i++)
{
TreeNode *node=que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
if(i==0)
result=node->val;
}
}
return result;
}
};
这是迭代法,更好理解,就是层序遍历!
112. 路径总和 113.路径总和ii
112.路径总和
深度遍历,可以理解为前中后序遍历都可以,因为对中没有操作。其实这里也有一个控制循环不变量的想法,就是我们保证每次函数传入前我们都已经对传入节点的值进行过处理,就是减去传入节点的val。所以在根节点的时候也要先减去再传入。一定要记得根节点的判空操作。
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root!=nullptr)
return traveral(root,targetSum-root->val);
else return false;
}
bool traveral(TreeNode *node,int count)
{
if(node==nullptr&&count!=0) return false;
if(node->left==nullptr&&node->right==nullptr)
{
if(count==0) return true;
else return false;
}
if(node->left)
{
if(traveral(node->left,count-node->left->val))
return true ;
}
if(node->right)
{
if(traveral(node->right,count-node->right->val))
return true;
}
return false;
}
};
113.路径总和ii
思路和上道题一样,但是需要传回路径,所以需要在终止条件的时候push一下,注意回溯操作!
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void traversal(TreeNode* cur, int count) {
if (!cur->left && !cur->right && count == 0) {
result.push_back(path);
return;
}
if (!cur->left && !cur->right) return ; //
if (cur->left) {
path.push_back(cur->left->val);
count -= cur->left->val;
traversal(cur->left, count);
count += cur->left->val;
path.pop_back();
}
if (cur->right) {
path.push_back(cur->right->val);
count -= cur->right->val;
traversal(cur->right, count);
count += cur->right->val;
path.pop_back();
}
return ;
}
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
result.clear();
path.clear();
if (root == nullptr) retur
traversal(root, sum - root->val);
return result;
}
};
106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
106.从中序与后序遍历序列构造二叉树
第一遍写其实应该做日志,这样来方便debug。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0||postorder.size()==0)
return nullptr;
return traversal(inorder,postorder);
}
TreeNode *traversal(vector<int>& inorder, vector<int>& postorder)
{
if(postorder.size()==0) return nullptr;
int rootval=postorder[postorder.size()-1];
TreeNode *root=new TreeNode(rootval);
if(postorder.size()==1) return root;
int index=0;
for(index=0;index<inorder.size();index++)
{
if(rootval==inorder[index]) break;
}
vector<int> left_inorder(inorder.begin(),inorder.begin()+index);
vector<int> right_inorder(inorder.begin()+index+1,inorder.end());//左闭右开//
postorder.resize(postorder.size()-1);
vector<int> left_postorder(postorder.begin(),postorder.begin()+left_inorder.size());
vector<int> right_postorder(postorder.begin()+left_inorder.size(),postorder.end());
root->left=traversal(left_inorder,left_postorder);
root->right=traversal(right_inorder,right_postorder);
return root;
}
};
105.从前序与中序遍历序列构造二叉树
有一个很容易错的点就是在分割数组的时候忘记➕1,因为我们的前序数组的头是无用的数
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0)
return nullptr;
return traversal(preorder,inorder);
}
TreeNode *traversal(vector<int>& preorder, vector<int>& inorder)
{
if(preorder.size()==0) return nullptr;
int rootval=*preorder.begin();
TreeNode *root=new TreeNode(rootval);
if(preorder.size()==1) return root;
int index=0;
for(index=0;index<inorder.size();index++)
{
if(rootval==inorder[index]) break;
}
vector<int> left_inorder(inorder.begin(),inorder.begin()+index);
vector<int> right_inorder(inorder.begin()+index+1,inorder.end());
vector<int> left_preorder(preorder.begin()+1,preorder.begin()+left_inorder.size()+1);
vector<int> right_preorder(preorder.begin()+left_inorder.size()+1,preorder.end());
root->left=traversal(left_preorder,left_inorder);
root->right=traversal(right_preorder,right_inorder);
return root;
}