题目地址:https://leetcode.com/problems/binary-tree-level-order-traversal/
question:
my thinking:
和上篇文章http://blog.csdn.net/shangmingyang/article/details/45076337讲解的题目类似,这道题目也是涉及图的遍历的,显然对于这道题来说BFS要更简单一些,相比于一般的BFS遍历,这里要做的额外的工作就是解决遍历过程中节点所在层次的问题,即在遍历的时候还要确定哪几个节点是在同一行的,要保证他们要加入到同一个集合中。因为按照我们正常的遍历的话也是从上到下从左到右遍历的,从直观上看,只要节点在同一行他们就要加入到同一个集合中去,基于这个思路,在这里我采用了一个map来记录节点和节点所在层次的对应关系,在遍历的过程中不仅要把孩子节点插入到队列中,还要把孩子节点和所在层次插入到map中,有了这些数据,我们就可以去判断如果现在从队列首部拿出来的节点的所在层次大于之前记录的层次说明现在已经到了节点树的下一行,这时就可以把之前添加的节点集合加入到总集合去了,因为现在我们是只有到新一行的时候才将之前的节点集合加入到总集合众去,这样就实现了一行节点总在一个列表中的效果
my answer:
c++
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int> > levelOrder(TreeNode *root) {
vector<vector<int> > nodes;
if(root==NULL){
return nodes;
}
vector<int> newNodes;
map<TreeNode *,int> nodesMap;
queue<TreeNode *> nodesQueue;
int currLevel = 0;
TreeNode *currNode = NULL;
nodesQueue.push(root);
nodesMap.insert(pair<TreeNode *,int>(root,0));
while(!nodesQueue.empty()){
currNode = nodesQueue.front();
nodesQueue.pop();
if(nodesMap.find(currNode)->second>currLevel){
//此时换行
currLevel += 1;//更新当前行
nodes.push_back(newNodes); //加入到总集合中去
newNodes = vector<int>();//重新建立集合
}
newNodes.push_back(currNode->val);
TreeNode *leftChild = currNode->left;
TreeNode *rightChild = currNode->right;
//将子节点插入到queue中并将子节点和所在层次插入到map中
if(leftChild!=NULL){
nodesMap.insert(pair<TreeNode *,int>(leftChild,nodesMap.find(currNode)->second+1));
nodesQueue.push(leftChild);
}
if(rightChild!=NULL){
nodesMap.insert(pair<TreeNode *,int>(rightChild,nodesMap.find(currNode)->second+1));
nodesQueue.push(rightChild);
}
}
nodes.push_back(newNodes); //记得把最后一行添加进去
return nodes;
}
};
code explation:
代码里写的挺清楚了就不多说了,需要注意的是在前面的思路里我也说过,我们是在换行的时候才把之前的节点行加入总集合中去,而最后一行是碰不见换行的,所以最后要手动加入最后一行,看leetcode上的答案大体思路是一样的,只不过记录的是当前行的节点数量和下一行的节点数量以及当前行内已访问的节点数量,有兴趣的可以到这里看看:http://fisherlei.blogspot.com/2013/01/leetcode-binary-tree-level-order.html,下一道题目Binary Tree Level Order Traversal II就在代码最后把nodes翻转一下就好,在algorithm库里有相应的函数,reverse(nodes.begin(),nodes.end())
没想到的是这道题目我竟然一次就通过了,虽然很简单,但也能证明之前的训练还是起作用的,所以有想了解算法又不是做ACM的朋友可以试试leetcode再结合基本算法书看看应该是会有所提高的。