【二叉树专题】多次被考察真题:剑指 Offer 32 – III. 从上到下打印二叉树

本问题对应课程链接:剑指offer刷题第七期

要求:

1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。
2、给出你代码所用的时间复杂度和空间复杂度

共以下 20 个回答

  • 岱 永久会员 2024年12月26日 下午11:27

    LCR 151. 彩灯装饰记录 III

    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
    
            Boolean f = true;
            Queue<TreeNode> queue  = new LinkedList<>();
            List<List<Integer>> ans = new ArrayList<>();
            if(root == null) return ans;
            queue.add(root);
            while(!queue.isEmpty()){
                List<Integer> t = new ArrayList<>();
                Stack<Integer> s = new Stack<>();
                for(int i = queue.size(); i>0; i--){//一行
                    if(f == true){//正序
                        TreeNode node =  queue.poll();
                        t.add(node.val);
                        if(node.left!=null) queue.add(node.left);
                        if(node.right!=null) queue.add(node.right);
                    }else{//反序
                        TreeNode node =  queue.poll();
                        s.add(node.val);
                        if(node.left!=null) queue.add(node.left);
                        if(node.right!=null) queue.add(node.right);
                    }
                }
                if(f == true) ans.add(t); 
                if(f == false){
                    while(!s.isEmpty()){
                        t.add(s.pop());
                    }
                    ans.add(t); 
                }
                f=!f;
            }
            return ans;
        }
    }
    
    0 赞同 0 条回复
  • mpweixin用户 普通 2024年12月16日 下午11:53
    class Solution {
    public:
        vector<vector<int>> decorateRecord(TreeNode* root) {
            vector<vector<int>> result;
            if(root == NULL) return result;
            queue<TreeNode*> q;
            q.push(root);
            bool f = false;
            while(!q.empty()){
                int num = q.size();
                vector<int> t_result;
                while(num != 0){
                    TreeNode* temp = q.front();
                    q.pop();
                    num--;
                    t_result.push_back(temp->val);
                    if(temp->left) q.push(temp->left);
                    if(temp->right) q.push(temp->right);
                }
                if(f){
                    reverse(t_result.begin(), t_result.end());
                    f = false;
                }
                else{
                    f = true;
                }
                result.push_back(t_result);
            }
            return result;
        }
    };
    

    时间O(N),空间O(N)

    0 赞同 0 条回复
  • 🌟 普通 2024年12月14日 下午9:34

    //加了一个标志位判断是否把容器反转
    class Solution {
    public:
    vector<vector> decorateRecord(TreeNode* root) {
    queue<TreeNode> node;
    vector<vector> result;
    if (root != nullptr) {
    node.push(root);
    }
    bool ltor = true;
    while (!node.empty()) {
    vector
    temp;
    int size = node.size();
    bool targ = false;
    for (int i = 0; i < size; ++i) {
    TreeNode
    cur = node.front();
    node.pop();
    temp.push_back(cur->val);

                if (cur->left)
                    node.push(cur->left);
    
                if (cur->right)
                    node.push(cur->right);
            }
            if (ltor) {
                result.push_back(temp);
                ltor = false;
            } else {
                reverse(temp.begin(), temp.end());
                result.push_back(temp);
                ltor = true;
            }
        }
        return result;
    }
    

    };

    0 赞同 0 条回复
  • 陆狗陆狗 普通 2024年12月4日 下午10:08

    题解
    在上面一题的基础上,需要逆向数据的时候,其实不需要逆向遍历,正向遍历,通过list的addFirst逆向存储即可。

    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            if(root==null){
                // 错误点:int[]的new的方式
                return new ArrayList(0);
            }
            // 定义队列去按照访问顺序放入元素
            // 错误点:泛型元素的声明
            Queue<TreeNode> q= new LinkedList();
            // 定义链表存放值(因为个数不确定,不能建立数组了)
            List<List<Integer>> resultList=new ArrayList();
            q.offer(root);
            int cnt=0;
            while(!q.isEmpty()){
                // 每一行的长度
                int rowSize=q.size();
                // 存放一行节点的数据
                List<Integer> innerReslut=new ArrayList(rowSize);
                for(int i=0;i<rowSize;i++){
                    TreeNode tmpt= q.poll();
                    // 偶数就尾插,奇数就头插
                    if(cnt%2==0){
                         innerReslut.add(tmpt.val);
                    }else{
                        innerReslut.addFirst(tmpt.val);
                    }
                    // 左右节点放入队列中
                    if(tmpt.left!=null){
                        q.offer(tmpt.left);
                    }
                    if(tmpt.right!=null){
                        q.offer(tmpt.right);
                    }
                }
                // 值放入list中
                resultList.add(innerReslut);
                // 计数器
                cnt++;
            }
            return resultList;
        }
    }
    
    0 赞同 0 条回复
  • Tom Yuan 普通 2024年12月4日 下午12:57

    方法 和第二版本类似 但是添加一个指示器来确认是否要翻转存下来的list.

    class Solution:
        def decorateRecord(self, root: Optional[TreeNode]) -> List[List[int]]:
            if not root:
                return []
            queue: deque[TreeNode] = deque()
            queue.append(root)
            stack = []
            seq = True
            while queue:
                size_row = len(queue) # 当一个层级走完时,重新更新queue中的长度
                row = []
                while size_row: # 用缓存的层级长度来进行pop和找左右节点操作
                    node = queue.popleft()
                    row.append(node.val)
                    size_row -= 1
                    if node.left:
                        queue.append(node.left)
                    if node.right:
                        queue.append(node.right)
                if not seq:
                    stack.append(row[::-1])
                else: stack.append(row)
                seq = not seq
            return stack
    

    time O(n) space O(n)

    0 赞同 0 条回复
  • 无言 永久会员 2024年12月3日 下午5:30
    class Solution {
    public:
        vector<vector<int>> decorateRecord(TreeNode* root) {
            vector<vector<int>> ans;
            queue<TreeNode*> que;
            if(root) que.push(root);
            while(!que.empty()) {
                int len = que.size();
                vector<int> temp;
                while(len--) {
                    TreeNode* node = que.front();
                    temp.push_back(node->val);
                    que.pop();
                    if(node->left) que.push(node->left);
                    if(node->right) que.push(node->right);
                }
                if(ans.size() % 2 == 1) reverse(temp.begin(),temp.end());
                ans.push_back(temp);
            }
            return ans;
        }
    };
    时间复杂度 O(N)
    空间复杂度 O(N) 
    
    0 赞同 0 条回复
  • Pendulumpal 普通 2024年12月2日 下午9:30

    加入数组反转操作

        public List<List<Integer>> decorateRecord(TreeNode root) {
            boolean flag=false;
            List<List<Integer>> res = new ArrayList<>();
            if(root==null)return res;
            Queue<TreeNode> queue = new LinkedList<>(){{ add(root); }};
            while(!queue.isEmpty()) {
                List<Integer>tmp=new ArrayList<>();
                for(int i=queue.size();i>0;i--){
                    TreeNode node=queue.poll();
                    tmp.add(node.val);
                    if(node.left != null) queue.add(node.left);
                    if(node.right != null) queue.add(node.right);
                }
                if(flag)Collections.reverse(tmp);
                flag=!flag;
                res.add(tmp);
            }
            return res; 
        }
    
    0 赞同 0 条回复
  • YULONG 永久会员 2024年11月30日 下午6:09
    /**
    方法一:层次遍历模版
    加一个flag判断是否要把该层结果逆序
     */
    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
    
                    if (root == null){
                return new ArrayList<>();
            }
    
            Deque<TreeNode> q = new ArrayDeque<>();
            List<List<Integer>> res = new ArrayList<>();
    
            q.add(root);
    
            int flag = 0;
    
            while (q.size() > 0){
    
                List<Integer> oneRes = new ArrayList<>();
                int sz = q.size();
    
                for (int i = 0; i < sz; i++){
                    TreeNode node = q.pop();
                    oneRes.add(node.val);
                    if (node.left != null){
                        q.add(node.left);
                    }
                    if (node.right != null){
                        q.add(node.right);
                    }
                }
    
                if (flag == 1){
                    List<Integer> oneResNew = new ArrayList<>();
                    for (int i = oneRes.size() - 1; i >= 0; i--){
                        oneResNew.add(oneRes.get(i));
                    }
                    oneRes = oneResNew;
                }
    
                flag = (flag + 1) % 2;
                res.add(oneRes);
    
            }
    
            return res;
    
        }
    }
    
    0 赞同 0 条回复
  • Xiang. 永久会员 2024年11月30日 下午3:16
    思路:跟上一题的区别是加一个判断标志,奇数次时就将当前层数组进行反转。
    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            List<List<Integer>> res = new ArrayList();
            Queue<TreeNode> queue = new LinkedList<>();
            if (root == null)
                return res;
            queue.offer(root);
            int num=0;
            while (!queue.isEmpty()) {
                List<Integer> resList=new ArrayList();
                for(int i = queue.size(); i > 0; i--){   //q.size()会随每一次q.poll()而减少,所以必须从高到低定义循环
                    TreeNode tmp=queue.poll();
                    resList.add(tmp.val);
                    if(tmp.left!=null) queue.offer(tmp.left);
                    if(tmp.right!=null) queue.offer(tmp.right);
                }
                if(num%2!=0) Collections.reverse(resList);
                res.add(resList);
                num++;
            }
            return res;
        }
    }
    时间复杂度:O(n)
    空间复杂度:O(n)
    
    0 赞同 0 条回复
  • Renasc 普通 2024年11月30日 上午10:16

    时间复杂度O(n), 空间复杂度O(n)

    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            // 如果为空,直接返回
           if (root == null) return new ArrayList<>();
    
           // 创建结果集合
           List<List<Integer>> res = new ArrayList<>();
    
            // 创建双端队列
            Queue<TreeNode> dqueue = new LinkedList<>(){{offer(root);}};
    
            // 开始循环遍历队列
            while (!dqueue.isEmpty()) {
                // 创建每层临时集合
                List<Integer> temp = new ArrayList<>();
    
                // 循环每一层
                for (int i=dqueue.size(); i>0; i--) {
                    // 出队
                    TreeNode node = dqueue.poll();
                    // 添加元素到每一层的临时集合
                    if (res.size() % 2 == 0) {
                        temp.addLast(node.val);
                    } else {
                        temp.addFirst(node.val);
                    }
                    // 遍历左右子树
                    if (node.left != null) dqueue.offer(node.left);
                    if (node.right != null) dqueue.offer(node.right);
                }
                // 添加每一层到总结果层
                res.add(temp);
            }
            // 返回结果
            return res;
        }
    }
    
    0 赞同 0 条回复
  • Kisara 普通 2024年11月30日 上午8:27

    当层数为偶数的时候就反转集合,或者存入栈再取出

    /**
     * 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 {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            Queue<TreeNode> queue=new LinkedList<>();
            List<List<Integer>> res=new ArrayList<>();
            if(root!=null) queue.add(root);
    
            int count=1;
            while(!queue.isEmpty()){
                List<Integer> list=new ArrayList<>();
                for(int i=queue.size();i>0;i--){
                    TreeNode node=queue.poll();
                    list.add(node.val);
                    if(node.left!=null) queue.add(node.left);
                    if(node.right!=null) queue.add(node.right);
                }
                if(count%2==0) {
                        Collections.reverse(list);
                    }
                count++;
                res.add(list);
            }
    
            return res;
        }
    }
    

    On On

    0 赞同 0 条回复
  • youngsir 普通 2024年11月29日 下午8:18

    打卡

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> decorateRecord(TreeNode* root) {
            vector<vector<int>> res;
            if(root == NULL){
                return {};
            }
            queue<TreeNode*>q;
            int sum = 1;
            q.push(root);
            while(!q.empty()){
                int n = q.size();
                vector<int> v(n);
                for(int i = 0;i < n;i++){
                    TreeNode* t = q.front();
                    q.pop();
                    if(sum % 2 == 1){
                        v[i] = t->val;
                    }else{
                        v[n - 1 - i] = t->val;
                    }
                    if(t->left){
                        q.push(t->left);
                    }
                    if(t->right){
                        q.push(t->right);
                    }
                }
                res.push_back(v);
                sum++;
            }
            return res;
    
    
        }
    };
    
    0 赞同 0 条回复
  • 黑键〰 普通 2024年11月29日 下午7:21
    /**
     * Definition for a binary tree node.
     * function TreeNode(val, left, right) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.left = (left===undefined ? null : left)
     *     this.right = (right===undefined ? null : right)
     * }
     */
    /**
     * @param {TreeNode} root
     * @return {number[][]}
     */
    var decorateRecord = function(root) {
        if(!root) return []
        let q = [root]
        let res = []
        let direction = true
        while(q.length > 0) {
            let len = q.length
            let level = []
            while(len) {
                let cur = q.shift()
                if(cur.left) q.push(cur.left)
                if(cur.right) q.push(cur.right)
                if(direction) {
                    level.push(cur.val)
                } else {
                    level.unshift(cur.val)
                }
                len--
            }
            res.push(level)
            direction = !direction
        }
        return res
    };
    

    思路:相对于上一题再加上一个flag,每层队列循环完之后取反
    根据flag的值来确认是从队头插入还是队尾

    0 赞同 0 条回复
  • Jerry 普通 2024年11月29日 下午4:57
    class Solution {
    public:
        vector<vector<int>> decorateRecord(TreeNode* root) {
            vector<vector<int>> ans;
            if(!root) return ans;
            queue<TreeNode*> q;
            int flag = 0;
            q.push(root);
            while(!q.empty()){
                vector<int> res;
                int sz = q.size();
                for(int i = 0; i < sz; i++){
                    TreeNode* tmp = q.front();
                    q.pop();
                    res.push_back(tmp->val);
                    if(tmp->left) q.push(tmp->left);
                    if(tmp->right) q.push(tmp->right);
                }
                if(flag){
                    reverseVcetor(res);
                }
                flag = flag ? 0:1;
                ans.push_back(res);
            }
            return ans;
        }
        void reverseVcetor(vector<int>& res){
            int sz = res.size();
            for(int i = 0, j = sz-1; i < sz && j>=0 && i<=j; i++,j--){
                int tmp = res[i];
                res[i] = res[j];
                res[j] = tmp;
            }
        }
    };
    

    时间o(n)空间o(n)

    0 赞同 0 条回复
  • Aatorx 永久会员 2024年11月29日 下午3:46
    class Solution {
    public:
        vector<vector<int>> decorateRecord(TreeNode* root) {
            vector<vector<int>> res;
            queue<TreeNode*> q;
            if(root == nullptr){
                return res;
            }
            q.push(root);
            int k = 1;
            while(!q.empty()){
                int n = q.size();
                vector<int> v(n);
                for (int i = 0; i < n; i++){
                    TreeNode* temp = q.front();
                    q.pop();
                    // v[i] = temp->val;
                    if(k % 2 == 1){
                        v[i] = temp->val;
                    }else{
                        v[n-i-1] = temp->val;
                    }
                    if(temp->left != nullptr){
                        q.push(temp->left);
                    }
                    if(temp->right != nullptr){
                        q.push(temp->right);
                    }
                }
                k++;
                res.push_back(v);
            }
            return res;
        }
    };
    

    时间复杂度O(N),空间复杂度O(N)。

    0 赞同 0 条回复
  • 月下足迹 普通 2024年11月29日 上午11:39

    //在第二题的基础上加一个锁,为true就是从左到右,false为从右到左
    class Solution {
    public List<List> decorateRecord(TreeNode root) {
    Queue queue = new LinkedList<>();
    List<List> result = new ArrayList<>();
    if (root != null) queue.add(root);
    boolean lock = true;
    while(!queue.isEmpty()) {
    List
    tmp = new ArrayList<>();
    for (int i = queue.size(); i > 0; i–) {
    TreeNode tmpNode = queue.poll();
    tmp.add(tmpNode.val);
    if (tmpNode.left!=null) queue.add(tmpNode.left);
    if (tmpNode.right!=null) queue.add(tmpNode.right);
    }
    if (lock) {
    result.add(tmp);
    lock = !lock;
    } else {
    result.add(tmp.reversed());
    lock = !lock;
    }

        }
    
        return result;
    }
    

    }

    0 赞同 0 条回复
  • jaron 普通 2024年11月29日 上午9:51

    定义一个变量reverse,为true就反转

    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            List<List<Integer>> res = new ArrayList<>();
            if (root == null)
                return res;
            Queue<TreeNode> q = new LinkedList<>();
            boolean reverse = false;
            q.add(root);
            while (!q.isEmpty()) {
                int n = q.size();
                List<Integer> sub = new ArrayList<>();
                for (int i = 0; i < n; i++) {
                    TreeNode temp = q.poll();
                    // 取的同时,有左加左,有右加右
                    sub.add(temp.val);
                    if (temp.left != null)
                        q.add(temp.left);
                    if (temp.right != null)
                        q.add(temp.right);
                }
                if (reverse) {
                    Collections.reverse(sub);
                }
                res.add(sub);
                reverse = !reverse;
            }
            return res;
        }
    }
    
    0 赞同 0 条回复
  • 苯庸 普通 2024年11月29日 上午9:48

    class Solution {
    public List<List> decorateRecord(TreeNode root) {
    List<List
    > res = new ArrayList();
    if(root null) return res;
    Deque deque = new ArrayDeque();
    deque.offer(root);
    int depth = 0;
    while(!deque.isEmpty()){
    int size = deque.size();
    List list = new ArrayList();
    while(size– > 0){
    TreeNode cur = deque.poll();
    list.add(cur.val);
    if(cur.left != null){
    deque.offer(cur.left);
    }
    if(cur.right != null){
    deque.offer(cur.right);
    }
    }
    if(++depth % 2
    0) Collections.reverse(list);
    res.add(list);
    }
    return res;
    }
    }
    层次遍历,记录深度,偶数则将结果reverse
    时间:O(n)
    空间:O(n)

    0 赞同 0 条回复
  • lQl 永久会员 2024年11月28日 下午10:31

    当层数为偶数时用栈存储然后再导入,相当于反过来
    时间复杂度O(n)
    空间复杂度O(n)

    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            Queue<TreeNode> tree = new LinkedList<>();
            List<List<Integer>> ans = new ArrayList<>();
            if (root != null)
                tree.offer(root);
            int ceng = 1;
            while (!tree.isEmpty()) {
                List<Integer> tmp = new ArrayList<>();
                int n = tree.size();
    
                if (ceng % 2 == 0) {
                    Stack<Integer> t = new Stack<>();
                    for (int i = 0; i < n; i++) {
                        TreeNode node = tree.poll();
                        t.push(node.val);
                        if (node.left != null)
                            tree.offer(node.left);
                        if (node.right != null)
                            tree.offer(node.right);
                    }
                    while(!t.empty()){
                        tmp.add(t.pop());
                    }
                } else {
                    for (int i = 0; i < n; i++) {
                        TreeNode node = tree.poll();
                        tmp.add(node.val);
                        if (node.left != null)
                            tree.offer(node.left);
                        if (node.right != null)
                            tree.offer(node.right);
                    }
                }
    
                ans.add(tmp);
                ceng++;
                System.out.print(ceng);
    
            }
            return ans;
        }
    }
    

    看了题解可以知道用双端队列

    0 赞同 0 条回复
  • 迢迢星野 普通 2024年11月28日 下午8:04
    class Solution {
        public List<List<Integer>> decorateRecord(TreeNode root) {
            // 初始化结果列表
            List<List<Integer>> res = new ArrayList<>();
            // 如果根节点为空,直接返回空的结果列表
            if (root == null) {
                return res;
            }
    
            // 使用队列辅助进行层序遍历
            Queue<TreeNode> que = new LinkedList<>();
            // 将根节点加入队列开始遍历
            que.offer(root);
            // 记录当前层的奇偶性,false 表示奇数层,true 表示偶数层
            boolean flag = false;
    
            // 当队列不为空时,继续遍历
            while (!que.isEmpty()) {
                // 获取当前层的节点数量
                int size = que.size();
                // 初始化当前层的节点值列表
                List<Integer> level = new ArrayList<>();
                // 此时的 for 循环,遍历的就是同一层的节点
                for (int i = 0; i < size; i++) {
                    // 出队当前层的节点
                    TreeNode node = que.poll();
                    // 将节点值加入当前层的列表中
                    level.add(node.val);
                    // 如果当前节点有左子节点,加入队列以供下一层遍历
                    if (node.left != null) {
                        que.offer(node.left);
                    }
                    // 如果当前节点有右子节点,加入队列以供下一层遍历
                    if (node.right != null) {
                        que.offer(node.right);
                    }
                }
                if (flag) {
                    // 翻转这一层的结果
                    Collections.reverse(level);
                }
                // 将当前层的节点值列表加入结果列表中
                res.add(level);
                flag = !flag;
            }
            // 返回结果列表
            return res;
        }
    }
    

    思路:层序遍历,奇数层不需要反转当前层的节点,偶数层需要反转当前层的节点。
    时间复杂度:O(n)。
    空间复杂度:O(n)。

    0 赞同 0 条回复

# 回答此问题

后才能回答