李洪强iOS经典面试题35-按层遍历二叉树的节点

问题

给你一棵二叉树,请按层输出其的节点值,即:按从上到下,从左到右的顺序。

例如,如果给你如下一棵二叉树:

  1.    3
  2.   / \
  3.  9  20
  4.    /  \
  5.   15   7

输出结果应该是:

  1. [
  2.  [3],
  3.  [9,20],
  4.  [15,7]
  5. ]

代码模版

本题的 Swift 代码模版如下:

  1. private class TreeNode {
  2.    public var val: Int
  3.    public var left: TreeNode?
  4.    public var right: TreeNode?
  5.    public init(_ val: Int) {
  6.        self.val = val
  7.        self.left = nil
  8.        self.right = nil
  9.    }
  10. }
  11. class Solution {
  12.    func levelOrder(_ root: TreeNode?) -> [[Int]] {
  13.    }
  14. }

解答

本题出自 LeetCode 第 102 题,是一个典型的有关遍历的题目。为了按层遍历,我们需要使用「队列」,来将每一层的节点先保存下来,然后再依次处理。

因为我们不但需要按层来遍历,还需要按层来输出结果,所以我在代码中使用了两个队列,分别名为 level 和 nextLevel,用于保存不同层的节点。

最终,整个算法逻辑是:

  1. 判断输入参数是否是为空。
  2. 将根节点加入到队列 level 中。
  3. 如果 level 不为空,则:
    3.1 将 level 加入到结果 ans 中。
    3.2 遍历 level 的左子节点和右子节点,将其加入到 nextLevel 中。
    3.3 将 nextLevel 赋值给 level,重复第 3 步的判断。
  4. 将 ans 中的节点换成节点的值,返回结果。

因为我们是用 Swift 来实现代码,所以我使用了一些 Swift 语言的特性。例如:队列中我们保存的是节点的数据结构,但是最终输出的时候,我们需要输出的是值,在代码中,我使用了 Swift 的函数式的链式调用,将嵌套数组中的元素类型做了一次变换,如下所示:

  1. let ans = result.map { $0.map { $0.val }}

另外,我们也使用了 Swift 特有的 guard 关键字,来处理参数的特殊情况。

完整的参考代码如下:

  1. //
  2. //  Binary Tree Level Order Traversal.swift
  3. //
  4. //  Created by Tang Qiao.
  5. //
  6. import Foundation
  7. private class TreeNode {
  8.    public var val: Int
  9.    public var left: TreeNode?
  10.    public var right: TreeNode?
  11.    public init(_ val: Int) {
  12.        self.val = val
  13.        self.left = nil
  14.        self.right = nil
  15.    }
  16. }
  17. private class Solution {
  18.    func levelOrder(_ root: TreeNode?) -> [[Int]] {
  19.        guard let root = root else {
  20.            return []
  21.        }
  22.        var result = [[TreeNode]]()
  23.        var level = [TreeNode]()
  24.        level.append(root)
  25.        while level.count != 0 {
  26.            result.append(level)
  27.            var nextLevel = [TreeNode]()
  28.            for node in level {
  29.                if let leftNode = node.left {
  30.                    nextLevel.append(leftNode)
  31.                }
  32.                if let rightNode = node.right {
  33.                    nextLevel.append(rightNode)
  34.                }
  35.            }
  36.            level = nextLevel
  37.        }
  38.        let ans = result.map { $0.map { $0.val }}
  39.        return ans
  40.    }
  41. }

微信中排版代码非常不便,所以上述代码也可以从我的 Gist 中找到:https://gist.github.com/tangqiaoboy/a7d24ac5ca266d650aaa91615f39ffae

完成这道题的同学,可以试着练习一下 LeetCode 的第 107 题,看看能不能只改动一行代码,就把 107 题也解决掉。

欢迎大家把自己的代码也放到 gist 上回复给我,Objective-C 或 Swift 的都行。

玩得开心!

 

李洪强iOS经典面试题35-按层遍历二叉树的节点的更多相关文章

  1. 李洪强iOS经典面试题下

    李洪强iOS经典面试题下 21. 下面的代码输出什么? @implementation Son : Father - (id)init { self = [super init]; if (self) ...

  2. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  3. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  4. 李洪强iOS经典面试题154- 通知与推送

    李洪强iOS经典面试题154- 通知与推送   通知与推送 本地通知和远程推送通知对基本概念和用法? image 本地通知和远程推送通知都可以向不在前台运行的应用发送消息,这种消息既可能是即将发生的事 ...

  5. 李洪强iOS经典面试题153- 补充

    李洪强iOS经典面试题153- 补充   补充 有空就来解决几个问题,已经懒癌晚期没救了... UML 统一建模语言(UML,UnifiedModelingLanguage)是面向对象软件的标准化建模 ...

  6. 李洪强iOS经典面试题147-WebView与JS交互

    李洪强iOS经典面试题147-WebView与JS交互   WebView与JS交互 iOS中调用HTML 1. 加载网页 NSURL *url = [[NSBundle mainBundle] UR ...

  7. 李洪强iOS经典面试题144-数据存储

    李洪强iOS经典面试题144-数据存储   数据存储 sqlite中插入特殊字符的方法和接收到处理方法. 除'其他的都是在特殊字符前面加"/",而 ' -> '' .方法:k ...

  8. 李洪强iOS经典面试题143-绘图与动画

    李洪强iOS经典面试题143-绘图与动画   绘图与动画 CAAnimation的层级结构 CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使 ...

  9. 李洪强iOS经典面试题142-第三方框架及其管理

    李洪强iOS经典面试题142-第三方框架及其管理   第三方框架及其管理 使用过CocoaPods吗?它是什么?CocoaPods的原理? CocoaPod是一个第三方库的管理工具,用来管理项目中的第 ...

  10. 李洪强iOS经典面试题141-报错警告调试

    李洪强iOS经典面试题141-报错警告调试   报错警告调试 你在实际开发中,有哪些手机架构与性能调试经验 刚接手公司的旧项目时,模块特别多,而且几乎所有的代码都写在控制器里面,比如UI控件代码.网络 ...

随机推荐

  1. adore-ng笔记和Linux普通用户提权

    官网:https://github.com/trimpsyw/adore-ng 安装: [root@xuegod63 ~]# unzipadore-ng-master.zip [root@xuegod ...

  2. Unity 打包发布Android新手教学 (小白都能看懂的教学 ) [转]

    版权声明:本文为Aries原创文章,转载请标明出处.如有不足之处欢迎提出意见或建议,联系QQ531193915 扫码关注微信公众号,获取最新资源 最近在Unity的有些交流群里,发现好多Unity开发 ...

  3. ASP.NET中使用TreeView显示文件

    在ASP.NET中,TreeView的使用很普遍,把它利用上来 首先加入TreeView控件 <asp:TreeView ID="driverInfoView" runat= ...

  4. JavaScript实现计算器功能

    截图 : cal.js var Class = {} ; Class.calculation = function(){ var calculation = {} ; calculation.resu ...

  5. unexpected token: * 和 java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to 解决办法

    一.unexpected token: *  的解决办法 首先要搞清楚sql与hql的区别! sql操作的是数据库表,而hql操作的是对象! sql中“select * from table”,而hq ...

  6. 【Networking】Libevent客户端例子

    [原]Libevent客户端例子 时间 -- :: luotuo44的专栏 原文 http://blog.csdn.net/luotuo44/article/details/34416429 主题 l ...

  7. Report Studio中树提示如何使用

    环境:比如在一个销售数据里面,用户既要选择年,又要选择月,还要选择日,或者是随意选择其中的一个作为筛选条件,如果是Cube的话是可以通过拖拉不同的维度层级来实现该功能的,但是如果是FM开发的DMR模型 ...

  8. 稍复杂的ionic例子:显示一个列表,并且允许点击进入列表项

    这个例子,按照MVC的方式进行了分层,下面是代码: demo3.htm <!DOCTYPE html> <html ng-app="app"> <he ...

  9. ibatis自定义数据类型在不支持中文的数据库存储汉字

    道理很简单,把gbk的汉字转换成iso编码存进数据库就可以了,读出来的时候把iso转换成gbk还原出原始的汉字. ibatis可以自定义类型处理器,在这里面做编码转换再适合不过了! sqlmap-co ...

  10. OpenJudge百炼习题解答(C++)--题4010:2011

    题: 总时间限制:  1000ms  内存限制:  65536kB 描写叙述 已知长度最大为200位的正整数n.请求出2011^n的后四位. 输入 第一行为一个正整数k,代表有k组数据,k<=2 ...