题目大意是把一颗树的所有节点记录下来,但是要求要以行为单位按根到叶子的顺序记录,而每一行又是从左到右记录。
先贴代码再解释:
/**
* Definition for a binary tree node.
* 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> > level;
if(root == NULL)
return level;
int temp[10000],num[10000];
memset(num,0,sizeof(num));
num[0] = 1;
int sum = 1;
int i = 1;
int count = 0;
queue<TreeNode*> bfs;
bfs.push(root);
while(!bfs.empty()){
TreeNode* node = bfs.front();
bfs.pop();
temp[count] = node->val;
count++;
if(node->left!=NULL){
bfs.push(node->left);
num[i]++;
sum++;
}
if(node->right!=NULL){
bfs.push(node->right);
num[i]++;
sum++;
}
if(count>=sum-num[i]){
i++;
}
}
int push_num = 0;
for(int j = 0;j < i-1;j++){
vector<int> sub_level;
for(int p = 0;p<num[j];p++){
sub_level.push_back(temp[push_num]);
push_num++;
}
level.push_back(sub_level);
}
return level;
}
};
我的方法是用广搜去遍历整棵树,在遍历的过程中用num数组去记录每一行有几个节点,比如说num[0] = 1。因为如果根节点不为空那么树的第一行只有一个节点——根节点。用temp数组去记录每一个节点的数值。在这个广搜中,只有当某个节点被pop()出去了,我才会把他记在temp数组里。那么这个算法的关键点就在于num数组要如何得到了。
我这里的思路是每当队列中新push进来一个元素那么就有num[i]++,而每当temp里面的节点数量(count)大于num数组除去最后一个元素后所有元素之和时,i++。下面我来做一下解释。
广搜算法中在对第i层节点做遍历的时候,会把第i层节点的所有子节点push进队列之中。所以我们就应该利用这个时候去得到第i+1层到底有几个节点,这也就是为什么我在每当队列中新push进来一个元素那么就有num[i]++。而当第i层的节点的所有子节点都被push进来之后,我们就会开始遍历第i+1层的节点,这个时候就应该去记录第i+2层有多少节点。我们要清楚count是已经遍历了的节点的个数。而num[i]是始终快count一步的,也就是我们在遍历第i层的时候,num已经在记录i+1层的数量了。所以当我们遍历完第i层,count应该等于num数组求和但要除去最后一个元素,而当count大于num数组求和但要除去最后一个元素时,说明我们开始遍历i+1层了,这个时候num数组也应该结束当前元素的记录,而开始计算下一个元素的数值了。
同时这道题目只需要删改一下就可以完成:
104.Maximum Depth of Binary Tree (找到一颗树的深度)
107.Binary Tree Level Order Traversal II (和这道题类似只是输出顺序是从叶子的那一行到根的那一行,每一行还是从左到右)