本题使用广度优先遍历的思路,可以轻松用实现出来(不用c的话)
广度优先遍历,会用到队列。首先把根节点放进队列,然后以队列不为空为条件,每从队首取出一个节点,就把它的子节点加入队尾,这样就实现了广度优先遍历。
* 如果采用先进后出的策略,则是深入优先遍历。
# Definition for a binary tree node.
# class TreeNode
# attr_accessor :val, :left, :right
# def initialize(val)
# @val = val
# @left, @right = nil, nil
# end
# end
# @param {TreeNode} root
# @return {Integer[][]}
def level_order(root)
ret=[]
q= Queue.new
return [] if root == nil
q.enq [root,0]
while !q.empty? do
node = q.deq
if ret[node[1]].nil?
ret[node[1]]= [node[0].val]
else
ret[node[1]].push node[0].val
end
q.enq [node[0].left,node[1]+1] if node[0].left !=nil
q.enq [node[0].right,node[1]+1] if node[0].right !=nil
end
return ret
end
但是如果想用c实现,就很麻烦了。没有队列,没有动态数组。。。。
其中队列并不是必须的,因为我们并不关心真实的访问顺序,只要按照层级顺序返回结果就行,所以只需要在递归中加入记录层级的参数,并按照层级保存节点值就可以。
但是动态数组。。。本来想要绕过动态数组来实现,先按照二叉树的最大可能(如果root为第0层级,第n层最多有2^n个节点)申请一组数组来保存遍历结果,然后再按照得到的每层的实际节点数来申请一个小一点的数组,把之前得到的结果拷贝进去。
不过。。当我看到测试数据里面有一个几百次层,每层只有一个节点的树的时候,就放弃了这种解法了。
最后还是没有绕开动态数组,在英文版leetcode上参考了别人的实现。不得不吐槽一下,感觉中文leetcode太冷清,根本没有人讨论问题。。。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *columnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int get_height(struct TreeNode* node, int level);
int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) {
if(!root) return NULL;
int i,j;
int height = get_height(root, 1);
*returnSize = height;
int **temp_ret = malloc(height*sizeof(int*));
int *indices = (int*)malloc(height*sizeof(int));
memset(indices, 0, height*sizeof(int));
for(i=0;i<height;i++){
temp_ret[i] = NULL;
}
traverse(root,0,temp_ret,indices);
*columnSizes = indices;
return temp_ret;
}
int get_height(struct TreeNode* node, int level){
if(node){
int l = get_height(node->left, level+1);
int r = get_height(node->right, level+1);
return l>r? l:r;
}else{
return level-1;
}
}
void traverse(struct TreeNode* node, int level,int** ret, int* indices){
if(node){
arrayAdd(&ret[level], indices[level]++, node->val);
if(node->left)
traverse(node->left,level+1, ret, indices);
if(node->right)
traverse(node->right,level+1, ret, indices);
}
}
void arrayAdd (int** array, int size, int val)
{
int* temp = *array;
*array = (int *) calloc (size + 1, sizeof (int));
memcpy(*array,temp, size*sizeof(int));
free (temp);
(*array)[size] = val;
}