牛客题目
题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路
根据题意,每行的节点的访问顺序是相反的,我们可以用两个栈来隔行存储,一个栈中根据“左结点->右结点”的顺序访问另一个栈的栈顶元素,而另一个栈根据“右子树->左子树”的顺序访问另一个栈的栈顶元素,直到两个栈都为空。
代码上也有详细注释:
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) {
// 先创建一个需要返回的对象
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
// 判断传进来的根是否为null,如果是,则直接返回
if(pRoot == null){
return result;
}
// 创建两个栈,用来隔层存储
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
// 创建一个arrayList,存储每个节点的值,再存入要返回的对象中
ArrayList<Integer> arrayList = new ArrayList<>();
// 先添加第一个元素
arrayList.add(pRoot.val);
// 将arrayList直接存入要返回的result中,因为第一行只有一个根
result.add(arrayList);
// 将第一行压入第一个栈中
stack1.push(pRoot);
// 判断只要有一个栈不为null就进入
while(!stack1.isEmpty() || !stack2.isEmpty()){
// 一行存储完了之后,每次重新给arrayList赋一个新对象
arrayList = new ArrayList<>();
// 如果stack2是空的,则说明上层是存储在stack1中的,本层应该存入stack2中
if(stack2.isEmpty()){
// 判断stack1不为空,直到stack1为空为止,
// 也就是一直将上一行的元素都从stack1中出完并且将本行的所有元素都压入stack2中
while(!stack1.isEmpty()) {
if(stack1.peek().right != null){
arrayList.add(stack1.peek().right.val);
stack2.push(stack1.peek().right);
}
if(stack1.peek().left != null){
arrayList.add(stack1.peek().left.val);
stack2.push(stack1.peek().left);
}
stack1.pop();
}
}
// 同理处理stack1为空的时候,说明上一层存储在stack2中
else {
while(!stack2.isEmpty()) {
if(stack2.peek().left != null){
arrayList.add(stack2.peek().left.val);
stack1.push(stack2.peek().left);
}
if(stack2.peek().right != null){
arrayList.add(stack2.peek().right.val);
stack1.push(stack2.peek().right);
}
stack2.pop();
}
}
// 每一层处理完之后,要将arrayList添加到要返回的对象result中
if(arrayList.size() > 0){
result.add(arrayList);
}
}
return result;
}
}
思路清晰,代码简单,这下全懂了吧 ^_^ !
LeetCode上的题目
Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its zigzag level order traversal as:
[
[3],
[20,9],
[15,7]
]
代码:逻辑和上面是一模一样的
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
List<Integer> list = new ArrayList<>();
// 先添加第一个元素
list.add(root.val);
result.add(list);
stack1.push(root);
while (!stack1.isEmpty() || !stack2.isEmpty()) {
list = new ArrayList<>();
if (stack2.isEmpty()) {
while (!stack1.isEmpty()) {
if (stack1.peek().right != null) {
list.add(stack1.peek().right.val);
stack2.push(stack1.peek().right);
}
if (stack1.peek().left != null) {
list.add(stack1.peek().left.val);
stack2.push(stack1.peek().left);
}
stack1.pop();
}
}else {
while (!stack2.isEmpty()) {
if (stack2.peek().left != null) {
list.add(stack2.peek().left.val);
stack1.push(stack2.peek().left);
}
if (stack2.peek().right != null) {
list.add(stack2.peek().right.val);
stack1.push(stack2.peek().right);
}
stack2.pop();
}
}
if (list.size() > 0) {
result.add(list);
}
}
return result;
}
}