【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II

这篇具有很好参考价值的文章主要介绍了【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有LeetCode交流群/华为OD考试扣扣交流群可加:948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1336了解算法冲刺训练

题目链接

LeetCode103、二叉树的锯齿形层序遍历

题目描述

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

示例 1

【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II,LeetCode,# 二叉树,# BFS,java,c++,leetcode,算法,宽度优先,二叉树,python

输入:root = [3,9,20,null,null,15,7]
输出:[[[15,7],[20,9],[3]]

示例 2

输入:root = [1]
输出:[[1]]

示例 3

输入:root = []
输出:[]

提示

  • 树中节点数目在范围 [0, 2000]
  • -1000 <= Node.val <= 1000

解题思路

DFS和BFS异同

二叉树层序遍历是一个非常经典的问题,属于必须掌握的题目。

所谓二叉树遍历(traversal)指的是按照一定次序系统地访问一棵二叉树,使每个节点恰好被访问一次

二叉树遍历实质上是二叉树的线性化,将树状结构变为线性结构

二叉树遍历有两大类:

  • 深度优先(depth first traversal,DFS):先完成一棵子树的遍历再完成另一棵
  • 广度优先(breath first traversal,BFS):先完成一层节点的遍历再完成下一层

DFS和BFS均为树/图的搜索方式,能够访问树/图中的所有节点。它们的特点可以从以下的比喻看出区别:

  • DFS:优先移动节点,当对给定节点尝试过每一种可能性之后,才退到前一节点来尝试下一个位置。就像一个搜索者尽可能地深入调查未知的地域,直到遇到死胡同才回头。(下图以前序遍历为例)

【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II,LeetCode,# 二叉树,# BFS,java,c++,leetcode,算法,宽度优先,二叉树,python

  • BFS:优先对给定节点的下一个位置进行进行尝试,当对给定节点尝试过每一种可能性之后,才移动到下一个节点。就像一只搜索军队铺展开来覆盖领土,直到覆盖了所有地域。

【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II,LeetCode,# 二叉树,# BFS,java,c++,leetcode,算法,宽度优先,二叉树,python

用队列维护的BFS

树的广度优先遍历亦可称为层序遍历。其核心特点为,从上到下、从左到右访问树中的节点,每一层的节点都按顺序出现。

【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II,LeetCode,# 二叉树,# BFS,java,c++,leetcode,算法,宽度优先,二叉树,python

本题就是二叉树BFS的板子题,必须掌握。

BFS通常需要通过维护一个先进先出 (First In First Out,FIFO) 的队列来实现。

【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II,LeetCode,# 二叉树,# BFS,java,c++,leetcode,算法,宽度优先,二叉树,python

我们需要构建一个队列q用于储存每一层的所有节点,然后执行while循环(循环不变量为q不为空):

  1. 获得当前队列长度qSize,为该层的节点个数
  2. 初始化一个空的子列表subList,用于储存二叉树该层所有节点的值
  3. 执行for循环,循环qSize次。每一次循环包含以下环节
    a. 令队列q的队头节点出队,记为node,并将其值node.val存入subList
    b. 若node的左孩子node.left存在,则令node.left从队尾入队
    c. 若node的右孩子node.right存在,则令node.right从队尾入队
    (这些后入队的节点会在下一层的遍历中被取出)
  4. 经过qSize次循环后,subList已经储存了这一层节点的所有值,将subList加入全局的答案变量ans

这样就就是二叉树BFS的基本过程,其中第3步是最关键的步骤

如果题目有明显地要求区分每一层的情况(比如本题要求每一层的节点值需要单独储存在一个子列表中),则循环qSize次这个步骤是必要的。

本题沿用了LeetCode102、二叉树的层序遍历的大体框架,但最后要求返回的结果是自底向上的层序遍历,只需要返回ans数组的反转即可。即

return ans[::-1] 

代码

Python

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None:
            return []
        ans = list()
        q = deque()
        q.append(root)
        # False表示当前需要从左往右;True表示当前需要从右往左
        flag = False
        while q:
            qSize = len(q)
            subList = list()
            for _ in range(qSize):
                node = q.popleft()
                subList.append(node.val)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
            if flag == False:
                ans.append(subList)
            else:
                ans.append(subList[::-1])
            flag = not flag
        return ans

Java

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        if (root == null) {
            return ans;
        }

        Deque<TreeNode> q = new LinkedList<>();
        q.offer(root);
        boolean flag = false;

        while (!q.isEmpty()) {
            int qSize = q.size();
            List<Integer> subList = new ArrayList<>();
            for (int i = 0; i < qSize; i++) {
                TreeNode node = q.poll();
                subList.add(node.val);
                if (node.left != null) {
                    q.offer(node.left);
                }
                if (node.right != null) {
                    q.offer(node.right);
                }
            }
            if (flag) {
                reverse(subList);
            }
            ans.add(subList);
            flag = !flag;
        }

        return ans;
    }

    private void reverse(List<Integer> list) {
        int left = 0, right = list.size() - 1;
        while (left < right) {
            int temp = list.get(left);
            list.set(left, list.get(right));
            list.set(right, temp);
            left++;
            right--;
        }
    }
}

C++

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        if (root == nullptr) {
            return ans;
        }

        queue<TreeNode*> q;
        q.push(root);
        bool flag = false;

        while (!q.empty()) {
            int qSize = q.size();
            vector<int> subList;
            for (int i = 0; i < qSize; ++i) {
                TreeNode* node = q.front();
                q.pop();
                subList.push_back(node->val);
                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            if (flag) {
                reverse(subList.begin(), subList.end());
            }
            ans.push_back(subList);
            flag = !flag;
        }

        return ans;
    }
};

时空复杂度

时间复杂度:O(N)。仅需一次遍历整棵树。

空间复杂度:O(M)M为层的最大节点数,队列所占空间。

相关习题

LeetCode101、对称二叉树

LeetCode102、二叉树的层序遍历

LeetCode103、二叉树的锯齿形层序遍历

LeetCode107、二叉树的层序遍历II

LeetCode199、二叉树的右视图

LeetCode429、N叉树的层序遍历

LeetCode513、找树左下角的值

LeetCode515、在每个树行中找最大值

LeetCode637、二叉树的层平均值

LeetCode655、输出二叉树

LeetCode662、二叉树的最大宽度

LeetCode993、二叉树的堂兄弟节点

LeetCode1161、最大层内元素和

LeetCode1302、层数最深叶子节点的和

LeetCode1609、奇偶树


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多文章来源地址https://www.toymoban.com/news/detail-831255.html

到了这里,关于【Py/Java/C++三种语言详解】LeetCode每日一题240216【二叉树BFS】LeetCode103、二叉树的层序遍历II的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【LeetCode】每日一题 -- 1240. 铺瓷砖 -- Java Version

    【LeetCode】每日一题 -- 1240. 铺瓷砖 -- Java Version

    题目链接 :https://leetcode.cn/problems/tiling-a-rectangle-with-the-fewest-squares/ 23.05.31 华为机试第二题 NP-Complete 问题 题解参考:Java DFS暴力递归(详细注释) … 题解思路 : 检查当前答案是否大于等于当前最佳答案,若是,则进行剪枝,回溯 检查正方形中是否有空位,若无空位,更新

    2024年02月08日
    浏览(8)
  • leetcode每日一题44

    图论 dfs/bfs dfs代码框架 思路:本题要求找到被x围绕的陆地,所以边界的陆地O肯定不符合条件。那么我们只要从周边找到陆地O然后 通过 dfs或者bfs 将周边靠陆地且相邻的陆地O都变成A,然后再去重新遍历地图的时候,把剩下的O变成X,再把所有的A变成O。 确认递归函数,参数

    2024年01月19日
    浏览(15)
  • LeetCode每日一题之 复写0

    LeetCode每日一题之 复写0

    目录 题目介绍: 算法原理: 特殊位置处理: 代码实现: 题目链接:. - 力扣(LeetCode) 这种对数组元素进行修改,移动的题目我们仍然可以使用双指针法,不过我们按照常规思路从左到右处理数组,不难发现如下这种问题: 当cur指向1时,让dest下一个元素复写cur指向的元素

    2024年04月23日
    浏览(15)
  • 【LeetCode】每日一题:移除元素

    【LeetCode】每日一题:移除元素

    目录  题目: 思想1:暴力解法 思想2:创建一个temp数组  思想3:双指针 👻内容专栏:《LeetCode刷题专栏》 🐨本文概括: 27.移除元素 🐼本文作者:花 碟 🐸发布时间:2023.4.15 https://leetcode.cn/problems/remove-element/   点击跳转到LeetCode平台OJ页面(27.移除元素)  👉 示例1: 解

    2023年04月19日
    浏览(14)
  • 每日一题:leetcode 57 插入区间

    给你一个  无重叠的  , 按照区间起始端点排序的区间列表。 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 示例 1: 示例 2: 示例 3: 示例 4: 示例 5: 提示: 0 = intervals.length = 104 intervals[i].length == 2 0 = int

    2024年02月11日
    浏览(13)
  • Leetcode每日一题——“移除元素”

    Leetcode每日一题——“移除元素”

    各位CSDN的uu们你们好呀,小雅兰又来啦,今天,小雅兰的内容是移除元素,下面,让我们进入Leetcode的世界吧   说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以

    2023年04月23日
    浏览(5)
  • leetcode每日一题:62. 不同路径

    leetcode每日一题:62. 不同路径

    系列:动态规划 语言:java 难度:中等 题目来源:Leetcode62. 不同路径 开启动态规划章节了!!欢迎您在留言和我一起完成每日打卡,以后每天8点半前发布每日一题。 原题链接:Leetcode62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )

    2023年04月22日
    浏览(9)
  • 【LeetCode每日一题】——566.重塑矩阵

    【LeetCode每日一题】——566.重塑矩阵

    矩阵 简单 566.重塑矩阵 在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。 给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。 重构后

    2024年02月14日
    浏览(8)
  • 每日一题:LeetCode-75. 颜色分类

    每日一题:LeetCode-75. 颜色分类

    前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈    🔎🔎如果说代码有灵魂,那么它的灵魂一定是👉👉 算法 👈👈,因此,想要写出💚优美的程序💚,核心算法是必不可少的,少年,你渴望力量吗😆😆,想掌握程序的灵魂吗❓❗️那么就必须踏上这样一条漫长

    2024年02月04日
    浏览(9)
  • 每日一题(LeetCode)----二分查找(一)

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 示例 2: 示例 3: 提示: 1 = nums.length = 104 -104 = nums[i] = 104 nums 为 无重复元素 的 升序 排列数

    2024年02月08日
    浏览(6)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包