【每日一题】力扣103:二叉树的锯齿形层序遍历(两个栈实现)

题目描述(传送门

给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

示例

例如:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回锯齿形层序遍历如下:

[
  [3],
  [20,9],
  [15,7]
]

思路

使用两个栈结构,分别是左优先栈和右优先栈;
左优先栈:注意是入栈时先加入右子树在加入左子树,因为这样你的出栈顺序才是从左往右的。
右优先栈刚好相反:入栈时先加入左子树在加入右子树,因为这样你的出栈顺序才是从右往左的。

然后将root加入左优先栈,也就是第一层(从左往右遍历)。
进入循环,左优先栈出栈,右优先栈进栈。当左优先栈(当前层)出栈完毕这时右优先栈也就将下一层元素入栈完毕。
左优先栈空了说明一层结束,接下来右优先栈出栈,同时给左优先栈加入下一层元素。
这样循环通过左右优先栈实现锯齿形便利,当两个栈都为空时,则遍历结束。

可能有些绕,那就看代码注释:

代码

/**
 * 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>> list = new ArrayList<>();
        if (root == null) {
    
    
            return list;
        }
        Deque<TreeNode>  leftstack = new LinkedList<>();// 左优先栈(先加入右子树再加入右子树)
        Deque<TreeNode> rightstack = new LinkedList<>();// 右优先栈 与上边相反
        leftstack.push(root);//先从左往右,所以root加入左优先栈
        while (!leftstack.isEmpty() || !rightstack.isEmpty()) {
    
     //只要有一个不为空说明就没有便利结束
            // 因为第一层root已经加入左优先栈,下来就给右优先栈加入左右子树。
            // 如果不为空说明还是上一层的,只有空了才能加入
            if (rightstack.isEmpty()) {
    
    
                List<Integer> tempList = new ArrayList<>();
                while (!leftstack.isEmpty()) {
    
    // 左优先(本层)不为空,向右优先(下一层)加入左右子树
                    TreeNode temp = leftstack.peek();
                    tempList.add(temp.val);
                    //在这里,左优先栈是出栈状态,右优先栈是进栈状态。这和下边的进栈顺序不同也就实现锯齿形层序遍历
                    if (temp.left != null) {
    
    
                        rightstack.push(temp.left);
                    }
                    if (temp.right != null) {
    
    
                        rightstack.push(temp.right);
                    }
                    leftstack.pop();// 左优先出栈,左优先栈循环出栈,出栈时加入每个的左右子树
                }
                list.add(tempList);// 走到这里说明左优先栈为空了,说明本层也就便利完毕,同时下一层元素也就加入了右优先栈。将本层元素加入list
            } else {
    
    
                // 与上边刚好相反
                List<Integer> tempList = new ArrayList<>();
                while (!rightstack.isEmpty()) {
    
    
                    TreeNode temp = rightstack.peek();
                    tempList.add(temp.val);
                    if (temp.right != null) {
    
    
                        leftstack.push(temp.right);
                    }
                    if (temp.left != null) {
    
    
                        leftstack.push(temp.left);

                    }
                    rightstack.pop();
                }
                list.add(tempList);
            }
        }
        //走到这里,循环结束说明两个栈内都为空了,说明二叉树遍历完毕
        return list;


    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45532227/article/details/111538849
今日推荐