「剑指offer」 JZ77-按之字形顺序打印二叉树
「剑指offer」 JZ77-按之字形顺序打印二叉树
描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
例如:
给定的二叉树是{1,2,3,4,5}
该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
示例1
输入:{1,2,3,#,#,4,5}
返回值:[[1],[3,2],[4,5]]
说明:如题面解释,第一层是根节点,从左到右打印结果,第二层从右到左,第三层从左到右。
示例2
输入:{8,6,10,5,7,9,11}
返回值:[[8],[10,6],[5,7,9,11]]
示例3
输入:{1,2,3,4,5}
返回值:[[1],[3,2],[4,5]]
我的题解
这道题目也是考核的树的层序遍历,在树的层序遍历中需要理清楚节点出栈的顺序这道题目基本就可求解了。
代码如下:
import java.util.ArrayList;
import java.util.Stack;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
//特殊情况
//root为null
if(pRoot==null){
return new ArrayList<>();
}
//这就是二叉树的层序遍历
//这个每次需要考虑放入队列的次序,由于次序的特殊性可以确定使用栈来作为程序的数据结构
//如果认为root所在的层树为0层时,奇数层为从右到左,偶数层为从左到右
int level = 1;
Stack<TreeNode> stackA = new Stack();
Stack<TreeNode> stackB = new Stack();
ArrayList<ArrayList<Integer> > result = new ArrayList<>(); //依赖倒置原则
stackA.push(pRoot);
while(!stackA.empty()){
ArrayList<Integer> collection = new ArrayList<>();
if(level%2==0){
//偶数层 从左到右输出,也就是从右到左push
while(!stackA.empty()){
TreeNode temp = stackA.pop();
collection.add(temp.val);
if(temp.right!=null){
stackB.push(temp.right);
}
if(temp.left!=null){
stackB.push(temp.left);
}
}
}else{
// 奇数层从右到左输出,也就是从左到右push
while(!stackA.empty()){
TreeNode temp = stackA.pop();
collection.add(temp.val);
if(temp.left!=null){
stackB.push(temp.left);
}
if(temp.right!=null){
stackB.push(temp.right);
}
}
}
level++;
stackA = stackB;
stackB = new Stack<TreeNode>();
result.add(collection);
}
return result;
}
}
时间复杂度O(N):因为要遍历每一个节点
空间复杂度O(N):因为要新建栈放置每一个节点
学习到的新解法
解法:使用队列来求解
同样是层次遍历的思想,只不过使用队列来作为算法实现的数据结构。解法与使用栈的方法差别不大,就不放代码了。
1 初始情况,根结点入队列;
2 定义变量size记录当前队列长度;
3 对于「当前队列」,遍历其所有元素:依次出队列、访问该元素、左右孩子入队列。*注意:新入队列的「左右孩子」应当在下一层被访问,因此循环次数为size次。*
4 重复上述步骤直至队列为空。
步骤如图所示。