题目:
力扣leetcode-cn.com解题思路
层次遍历
这道题很容易想到广度优先遍历(BFS),但是课本上学的BFS并不是很适合此题,需要对层次遍历思想进行一定的改动,下面做个对比
代码对比
// 1.普通层次遍历思想
fun commonBfs(root: MultiTreeNode?) {
val queue = LinkedList<MultiTreeNode?>()
queue.add(root)
// while即用于控制层数也用于控制某层节点的遍历
while (queue.isNotEmpty()) {
val cur = queue.poll()
println(cur?.value)
queue.addAll(cur!!.nodes)
}
}
// 2.此题需要的思想
fun levelBfs(root: MultiTreeNode?) {
val queue = LinkedList<MultiTreeNode?>()
queue.add(root)
// while用于控制层数循环
while (queue.isNotEmpty()) {
val size = queue.size
// for用于控制某层节点的遍历
for (i in 0 until size) {
val cur = queue.poll()
println(cur?.value)
queue.addAll(cur!!.nodes)
}
}
}
通过上面代码可以发现,2中的方法用for
循环代替了一部分while
循环的路径,而得到了更多的信息就是层数和每层有哪些节点,而这些信息正是此题所需要的,具体的区别如下图:
![684e43e972eea9317ba320f27b3968df.png](https://i-blog.csdnimg.cn/blog_migrate/389e1debeb77e01727391f517c2a817f.jpeg)
代码
fun levelOrder2(root: Node?): List<List<Int>>? {
val result: MutableList<List<Int>> = ArrayList()
if (root == null) return result
val queue: Queue<Node?> = LinkedList()
queue.add(root)
// while循环遍历层数
while (!queue.isEmpty()) {
val level: MutableList<Int> = ArrayList()
val size = queue.size
// for循环遍历每层的所有节点
for (i in 0 until size) {
val node = queue.poll()
level.add(node!!.`val`)
// 添加该层节点的所有子节点
queue.addAll(node!!.children)
}
result.add(level)
}
return result
}
深度遍历
我们知道用深度遍历(DFS)是可以得到层数信息的,下面考虑我们应该在递归中的递还是归的过程中进行数据的填充,很明显在递的过程中对层数信息来得更明显,每递一次层数就加一,对每一层都设置一个List,如果没有List新建,如果有则通过索引即层数去获得已经创建的List, 然后再添加值就可以了。
代码
/**
* Definition for a Node.
* class Node(var `val`: Int) {
* var children: List<Node?> = listOf()
* }
*/
class Solution {
var resList = arrayListOf<ArrayList<Int>>()
fun levelOrder(root: Node?): List<List<Int>> {
helper(root, 0)
return resList
}
fun helper(root: Node?, depth: Int) {
if (root == null) return
// 在递的过程中的处理逻辑
if (depth >= resList.size) {
val newList = arrayListOf<Int>()
newList.add(root.`val`)
resList.add(newList)
} else {
// 层数信息即索引得到之前创建的List
resList[depth].add(root.`val`)
}
root.children.forEach {
helper(it, depth + 1)
}
}
}