Java——按之字形顺序打印二叉树

题目链接

牛客在线oj题——按之字形顺序打印二叉树

题目描述

给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)

数据范围:0≤n≤1500,
树上每个节点的val满足 ∣val∣<=1500
要求:空间复杂度:O(n),时间复杂度:O(n)

例如:
给定的二叉树是{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]]

思路一

定义一个栈stack和一个队列queue,boolean类型变量isRightToLeft = true,将根节点入栈

每次循环前创建ArrayList的list变量,用来存储每一层遍历的元素。确定当前栈的元素个数size(就是当前层所有元素的个数)。

从栈中取出元素,将该元素的值添加进list中,如果当前是需要从右到左遍历,那么先向queue存入当前节点的左子树,再存入右子树。否则先存入当前节点的右子树,再存入左子树(因为栈是先入后出,所以left应该被后遍历时应该被先压入栈)

每一层遍历后对isRightToLeft取反,然后向result中添加list中的元素,再向stack中插入queue中所有元素

而之所以需要定义queue,而不能直接将元素入栈,是因为由于栈是后入先出的,所以添加元素后会影响栈的弹出顺序,所以要等到一层都遍历完后再插入栈

思路一代码

import java.util.*;

/*
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<>();
        if(pRoot == null){
    
    
            return result;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();
        boolean isRightToLeft = true;

        stack.push(pRoot);

        while(!stack.isEmpty()){
    
    
            ArrayList<Integer> list = new ArrayList<>();
            int size = stack.size();

            while(size != 0){
    
    
                TreeNode cur = stack.pop();
                list.add(cur.val);
                TreeNode first = isRightToLeft ? cur.left : cur.right;
                TreeNode second = isRightToLeft ? cur.right : cur.left;

                if(first != null){
    
    
                    queue.add(first);
                }
                if(second != null){
    
    
                    queue.add(second);
                }
                size--;
            }

            isRightToLeft = !isRightToLeft;
            result.add(new ArrayList<>(list));
            while(!queue.isEmpty()){
    
    
                stack.add(queue.poll());
            }
        }
        return result;
    }
}

思路二

定义一个boolean类型的变量isLeftToRight,如果为true代表从左向右遍历

按照层序遍历的方法从上到下遍历二叉树,将每一层的节点存储在list中,如果isLeftToRight为false,那么就翻转list

最后将每一层的list存储在result中,直接返回即可

具体层序遍历的思路为:
定义一个队列queue,首先将根节点root进入队列,每次循环都先确定队列中元素个数size,每次弹出size个元素,这一次循环就是代表访问二叉树的一层的元素,然后再将这一层的元素的左子树和右子树(如果存在)分别加入到队列中即可

思路二代码

import java.util.*;

/*
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<>();
        if(pRoot == null){
    
    
            return result;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        boolean isLeftToRight = true;
        
        queue.add(pRoot);
        while(!queue.isEmpty()){
    
    
            int size = queue.size();
            ArrayList<Integer> list = new ArrayList<>();
            
            while(size != 0){
    
    
                TreeNode cur = queue.poll();
                list.add(cur.val);
                if(cur.left != null){
    
    
                    queue.add(cur.left);
                }
                if(cur.right != null){
    
    
                    queue.add(cur.right);
                }
                size--;
            }
            
            if(!isLeftToRight){
    
    
                Collections.reverse(list);
            }
            
            isLeftToRight = !isLeftToRight;
            result.add(new ArrayList<>(list));
        }
        return result;
    }

}

猜你喜欢

转载自blog.csdn.net/m0_60867520/article/details/130552420