JZ22 题解 | #从上往下打印二叉树#
从上往下打印二叉树
http://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701
题意分析
- 首先,这个题目没有说明数据是如何给出的,建议补一个样例的解释。另外,这个题目的难度应该属于简单范围。
这是我对本题样例的理解。 - 题目给出一个二叉树的先序遍历的序列,需要我们求出这个二叉树的层序遍历的序列。样例解释如上面所示。
前置知识
- 首先,我们需要知道什么是二叉树,简单来说就是一个一棵树由根节点,左叶子节点和右叶子节点组成,而左右叶子节点又可以单独看成一个二叉树。即每个节点最多有两个子节点。然后就是一层层的递归下去。
看一张图(有点丑,hhh) - 广度优先搜索(BFS)
广度优先搜索指的是以某一个点为中心,不断向外进行辐射。广度是他的第一关键字。总是先访问能直接到达的节点,然后以被访问的节点的顺序依次访问他们所能到达的节点。另外还有个深度优先搜索,这个可以自行去学习。
思路分析
写法一
- 我们发现,题目是按照一个二叉树的先序遍历的结果给我们,如果我们需要进行一个层序遍历。那么我们需要先访问当前这一层的节点,然后访问完这些节点之后,我们需要就可以按照被访问的顺序去继续访问他们能访问的节点了。对于BFS,我们可以利用一个队列来存储我们需要访问的节点。当我们访问一个节点的时候,将这个节点的权值放入最终的答案里面,然后这节点出队。然后我们先判断左边的节点是否为空,如果为空,那么将这个节点指针入队,对右边的节点的判断也是一样。一直执行下去直到最后队列为空。另外记得特判根节点为空的情况。
- 代码,时间复杂度为O(N),空间复杂度也是O(N)
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: vector<int> PrintFromTopToBottom(TreeNode* root) { vector<int> ans; // 特判为空的情况 if(!root) return ans; queue<treenode*> q; // 先将根节点放入队列里面 q.push(root); while(!q.empty()){ TreeNode* now = q.front(); // 出队 q.pop(); ans.push_back(now->val); // 左边结点不为空,先将左节点入队 if(now->left) q.push(now->left); // 右边结点不为空,将右结点入队 if(now->right) q.push(now->right); } return ans; } };写法二
- 这个题目的思路比较有限,所以我暂时想不到第二种写法了。我就来补充一个Go语言的写法吧。Go语言的写法需要注意的是Go语言中没有天然写好的队列,需要我们自己实现。不过幸好Go语言为我们提供了切片,所以我们用切片来模拟队列就行了。
- 代码如下
package main import . "nc_tools" func PrintFromTopToBottom( root *TreeNode ) []int { // write code here res := []int{} if(root==nil){ return res } var q = []*TreeNode{root} // 用切片来模拟队列,到了切片尾部说明这个队列为空 for i:=0;i<len(q);i++ { // 将当前结点入队 now := q[i] res=append(res,now.Val) // 依次判断左右结点是否可以入队 if(now.Left!=nil){ q=append(q,now.Left) } if(now.Right!=nil){ q=append(q,now.Right) } } return res }
查看1道真题和解析