leetcode--102--二叉树的层序遍历

难度: Medium
题目链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

二叉树的层序遍历

在这里插入图片描述
关于二叉树详细参考文章 数据结构与算法–Python–树

class Solution:
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        def dfs(node, level, res):
            if not node:
                return
            if len(res) < level: # 如果该层还未初始化
                res.append([])
            res[level-1].append(node.val) # 当前node属于第level层
            dfs(node.left, level+1, res) # node.left属于第level+1层
            dfs(node.right, level+1, res) # node.right属于第level+1层
                
        res = []
        dfs(root, 1, res)
        return res

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        dfs(res, root, 0);
        return res;
    }

    private void dfs(List<List<Integer>> res, TreeNode root, int level) {
        // 递归终止条件,root 为 null 则遍历结束
        if (root == null) {
            return;
        }
        // 根据 level 以及集合的大小判断是否需要加入新的层级,也就是新的的 List
        if (level >= res.size()) {
            res.add(new ArrayList<>());
        }
        res.get(level).add(root.val);
        // 向下一个 level 中的左树进行遍历
        dfs(res,root.left,level+1);
        // 向下一个 level 中的左树进行遍历
        dfs(res,root.right,level+1);
    }
}

使用自己实现 LoopQueue 进行提交

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private interface Queue<E> {

        int getSize();
        boolean isEmpty();
        void enqueue(E e);
        E dequeue();
        E getFront();
    }

    private class LoopQueue<E> implements Queue<E> {

        private E[] data;
        private int front, tail;
        private int size;  // 有兴趣的同学,在完成这一章后,可以思考一下:
        // LoopQueue中不声明size,如何完成所有的逻辑?
        // 这个问题可能会比大家想象的要难一点点:)

        public LoopQueue(int capacity){
            data = (E[])new Object[capacity + 1];
            front = 0;
            tail = 0;
            size = 0;
        }

        public LoopQueue(){
            this(10);
        }

        public int getCapacity(){
            return data.length - 1;
        }

        @Override
        public boolean isEmpty(){
            return front == tail;
        }

        @Override
        public int getSize(){
            return size;
        }

        @Override
        public void enqueue(E e){

            if((tail + 1) % data.length == front)
                resize(getCapacity() * 2);

            data[tail] = e;
            tail = (tail + 1) % data.length;
            size ++;
        }

        @Override
        public E dequeue(){

            if(isEmpty())
                throw new IllegalArgumentException("Cannot dequeue from an empty queue.");

            E ret = data[front];
            data[front] = null;
            front = (front + 1) % data.length;
            size --;
            if(size == getCapacity() / 4 && getCapacity() / 2 != 0)
                resize(getCapacity() / 2);
            return ret;
        }

        @Override
        public E getFront(){
            if(isEmpty())
                throw new IllegalArgumentException("Queue is empty.");
            return data[front];
        }

        private void resize(int newCapacity){

            E[] newData = (E[])new Object[newCapacity + 1];
            for(int i = 0 ; i < size ; i ++)
                newData[i] = data[(i + front) % data.length];

            data = newData;
            front = 0;
            tail = size;
        }

        @Override
        public String toString(){

            StringBuilder res = new StringBuilder();
            res.append(String.format("Queue: size = %d , capacity = %d\n", size, getCapacity()));
            res.append("front [");
            for(int i = front ; i != tail ; i = (i + 1) % data.length){
                res.append(data[i]);
                if((i + 1) % data.length != tail)
                    res.append(", ");
            }
            res.append("] tail");
            return res.toString();
        }
    }

    public List<List<Integer>> levelOrder(TreeNode root) {

        ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root == null)
            return res;

        // 我们使用LinkedList来做为我们的先入先出的队列
        LoopQueue<Pair<TreeNode, Integer>> queue = new LoopQueue<Pair<TreeNode, Integer>>();
        queue.enqueue(new Pair<TreeNode, Integer>(root, 0));

        while(!queue.isEmpty()){

            Pair<TreeNode, Integer> front = queue.dequeue();
            TreeNode node = front.getKey();
            int level = front.getValue();

            if(level == res.size())
                res.add(new ArrayList<Integer>());
            assert level < res.size();

            res.get(level).add(node.val);
            if(node.left != null)
                queue.enqueue(new Pair<TreeNode, Integer>(node.left, level + 1));
            if(node.right != null)
                queue.enqueue(new Pair<TreeNode, Integer>(node.right, level + 1));
        }

        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值