持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
题目
给定二叉树的根节点 root
,返回所有左叶子之和。
示例 1:
- 输入:
root = [3,9,20,null,null,15,7]
- 输出:
24
- 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
示例 2:
- 输入:
root = [1]
- 输出:
0
前言
一个节点为「左叶子」节点,当且仅当它是某个节点的左子节点,并且它是一个叶子结点。因此我们可以考虑对整棵树进行遍历,当我们遍历到节点 时,如果它的左子节点是一个叶子结点,那么就将它的左子节点的值累加计入答案。
遍历整棵树的方法有深度优先搜索和广度优先搜索,下面分别给出了实现代码。
方法一:深度优先搜索
代码
class Solution {
func isLeafNode(_ root: TreeNode?) -> Bool {
return nil == root?.left && nil == root?.right
}
func dfs(_ root: TreeNode?) -> Int {
var ans = 0
if nil != root?.left {
ans += isLeafNode(root?.left) ? root!.left!.val : dfs(root?.left)
}
if nil != root?.right && !isLeafNode(root?.right) {
ans += dfs(root?.right)
}
return ans
}
func sumOfLeftLeaves(_ root: TreeNode?) -> Int {
return nil != root ? dfs(root) : 0
}
}
复杂度分析
-
时间复杂度:,其中 是树中的节点个数。
-
空间复杂度:。空间复杂度与深度优先搜索使用的栈的最大深度相关。在最坏的情况下,树呈现链式结构,深度为 ,对应的空间复杂度也为 。
方法二:广度优先搜索
代码
class Solution {
func isLeafNode(_ root: TreeNode?) -> Bool {
return nil == root?.left && nil == root?.right
}
func sumOfLeftLeaves(_ root: TreeNode?) -> Int {
if nil == root {
return 0
}
var q: [TreeNode?] = []
q.append(root)
var ans: Int = 0
while !q.isEmpty {
let node: TreeNode? = q.removeFirst()
if nil != node?.left {
if isLeafNode(node?.left) {
ans += node!.left!.val
}
else {
q.append(node?.left)
}
}
if nil != node?.right {
if !isLeafNode(node?.right) {
q.append(node?.right)
}
}
}
return ans
}
}
复杂度分析
-
时间复杂度:,其中 是树中的节点个数。
-
空间复杂度:。空间复杂度与广度优先搜索使用的队列需要的容量相关,为 。