第0题:二叉树--层序遍历
用一个队列保存节点,然后将节点的值一层一层的放进vec中,然后将vec放进result中
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if(root!=NULL) que.push(root);
vector<vector<int>> result; //将vec按行信息放进去
while(!que.empty())
{
int size=que.size();
vector<int> vec; //将每行的值放进去
for(int i=0;i<size;i++)
{
TreeNode *node=que.front();
que.pop();
vec.push_back(node->val);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(vec);
}
return result;
}
};
第一题:找树左下角的值
也就是给定一个二叉树,在树的最后一行找到最左边的值。
注意左下角不是最左边,所以本题适合用迭代法层序遍历,只需要记录最后一行第一个节点就可以
1.相比原来的层序遍历,本题不需要记录所有结点的值,只需要一个result记录一个结点的值就可以了。
第二题:路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
递归三部曲:
(1)确定递归函数的参数和返回类型
bool traversal(treenode * cur,int count)
//返回的类型是在说明是否找到了符合要求的路径
(2)确定终止条件
计数器可以往上增,累和,也可以往下减,如果最后为0 ,则说找到了满足条件的路径;
if(!cur->left && !cur->right &&count==0) return true;
if(!cur->left && !cur->right) return false;
(3) 确定单层递归的逻辑
空节点不遍历,找到合适的路径,立刻返回;
if(cur->left){
if(traversal(cur->left,count-cur->left->val)) return ture;
}
if(cur->right){
if(traversal(cur->right,count-cur->right->val)) return true;
}
return false;
2. 回溯是什么
就是发现第一条路径不满足条件,回到刚刚最后一个叶子节点的父亲结点的右孩子
第三题 从中序和后序遍历序列构造二叉树
0.首先中序:左根右;后序:左右根
-
第一步:如果数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
-
第五步:切割后序数组,切成后序左数组和后序右数组
-
第六步:递归处理左区间和右区间
TreeNode* traversal(vector<int>& inorder, vector<int>& postorder)
{
//第一步
if(postorder.size()==0) return NULL;
//第二步 后序遍历最后一个元素就是当前的根节点
int rootValue=postorder[postorder.size()-1];
TreeNode* root=new TreeNode(rootValue);
//叶子节点
if(postorder.size()==1) return root;
//第三步,找切割点
int delimiterIndex;
for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++)
{
if(inorder[delimiterIndex]==rootValue) break;
}
//第四步:切割中序数组 得到 中序左数组和中序右数组
//左闭右开区间:[0,delimiterIndex)
vector<int> leftInorder(inorder.begin(),inorder.begin()+delimiterIndex);
//[delimiterIndex+1,end)
vector<int> rightInorder(inorder.begin()+delimiterIndex+1,inorder.end());
//舍弃末尾元素
postorder.resize(postorder.size()-1);
//第五步:切割后序数组,得到 后序左数组和后序右数组
//[0,leftInorder.size)
vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInorder.size());
//[leftInorder.size(),en)
vector<int> rightPostorder(postorder.begin()+leftInorder.size(),postorder.end());
//第六步
root->left=traversal(leftInorder,leftPostorder);
root->right=traversal(rightInorder,rightPostorder);
return root;
}
第四题 从前序与中序遍历序列构造二叉树
思路:本题和上一题思路一样,步骤也一样,前序遍历可以确定根节点,然后在中序遍历中切割成两个数组。多次迭代
非要说有什么不同,本题前序遍历的方向不一样:根左右,所以确定根节点值的时候,直接放前序数组的第一个值;以及将上一题中求数组长度的值直接用参数表示;