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

问题

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

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

    3
  / \
 9  20
   /  \
  15   7

输出结果应该是:

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

代码模版

本题的 Swift 代码模版如下:

private class TreeNode {
   public var val: Int
   public var left: TreeNode?
   public var right: TreeNode?
   public init(_ val: Int) {
       self.val = val
       self.left = nil
       self.right = nil
   }
} class Solution {
   func levelOrder(_ root: TreeNode?) -> [[Int]] {    }
}

解答

本题出自 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 的函数式的链式调用,将嵌套数组中的元素类型做了一次变换,如下所示:

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

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

完整的参考代码如下:

//
//  Binary Tree Level Order Traversal.swift
//
//  Created by Tang Qiao.
// import Foundation private class TreeNode {
   public var val: Int
   public var left: TreeNode?
   public var right: TreeNode?
   public init(_ val: Int) {
       self.val = val
       self.left = nil
       self.right = nil
   }
} private class Solution {
   func levelOrder(_ root: TreeNode?) -> [[Int]] {
       guard let root = root else {
           return []
       }
       var result = [[TreeNode]]()
       var level = [TreeNode]()        level.append(root)
       while level.count != 0 {
           result.append(level)
           var nextLevel = [TreeNode]()
           for node in level {
               if let leftNode = node.left {
                   nextLevel.append(leftNode)
               }
               if let rightNode = node.right {
                   nextLevel.append(rightNode)
               }
           }
           level = nextLevel
       }        let ans = result.map { $0.map { $0.val }}
       return ans
   }
}

微信中排版代码非常不便,所以上述代码也可以从我的 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. iOS:本地数据库sqlite的介绍

    一.数据库的概念: 1..什么是数据库 SQL Server 2010.Oracle.MySQL 关系数据库 NoSQL数据库-非关系型数据库   数据库主要由表组成 表由字段组成 数据 就是表中的记 ...

  2. 如何移植openwrt系统

    Cisco/Linksys在2003年发布了WRT54G这款无线路由器,同年有人发现它的IOS是基于Linux的,然而Linux是基于GPL许可证发布的,按照该许可证Cisco应该把WRT54G的IO ...

  3. 作用JavaScript访问和操作数据库

    JS操作 Access 数据库 <SCRIPT LANGUAGE="JavaScript"> <!-- var filePath = location.href. ...

  4. [ES6] 04. The let keyword -- 2 Fiald case

    Fiald case 1: let can work in it's block { let a = 10; var b = 1; } a // ReferenceError: a is not de ...

  5. (LeetCode 53)Maximum Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  6. 《Go并发编程实战》第2版 紧跟Go的1.8版本号

    文章作者:郝林(<Go并发编程实战 (第2版)>作者) 最终来了! 经过出版社的各位编辑.校对.排版伙伴与我的N轮PK和共同努力,<Go并发编程实战>第2版的全部内容最终全然确 ...

  7. Android反编译方法(class+xml)

    ps:对于软件开发人员来说,保护代码安全也是比较重要的因素之一,不过目前来说Google Android平台选择了Java Dalvik VM的方式使其程序很容易破解和被修改,首先APK文件其实就是一 ...

  8. B/S学习总结

    经过5个月的学习,B/S学习的项目完毕了. 尽管项目完毕了,可是感觉自己还是差非常远.会的太少了.须要在项目中不断实战吧.以下分别对每一个项目进行总结. 牛腩新闻公布系统 简单介绍: 跟着视频里面的牛 ...

  9. Jquery 选择器,分不清啊

    Jquery 选择器 Id选择器 Class选择器 总是记不清啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!

  10. ant design pro (六)样式

    一.概述 参看地址:https://pro.ant.design/docs/style-cn 基础的 CSS 知识或查阅属性,可以参考 MDN文档. 二.详细介绍 2.1.less Ant Desig ...