二叉树找到每层的最大元素

在二叉树的每一行中找到最大的值。

https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/

输入: 

          1
         / \
        3   2
       / \   \  
      5   3   9 

输出: [1, 3, 9]


每层中的最大元素, 自然想到了使用层次遍历, 但是层次遍历是不清楚层的开始和结束的, 所以还需要对层次遍历进行一下改造.

先说下标准的层次遍历, 需要使用一个队列结构

1. 先把根节点加入到队列中

2. 把队列的第一个元素出队, 出队的同时, 把此元素的left和right加入到队列末尾

3. 继续第二步直到队列为空. 出队的顺序即为层次遍历的结果.

我们可以观察下, 1->3->2->5->3->9, 上一层的节点出队完, 下一层的节点正好完全在队列中. 比如说, 1出队的时候, 3,2正好在队列中 , 3,2出队完, 5,3,9正好在队列中. 所以从根节点开始, 当上一层节点出队完成, 下一层节点完全在队列中.

我们可以修改下标准的层次遍历, 从根节点开始, 先记录下队列中的元素数量currentSize, 然后依次把0-currentSize之间的每个元素的left和right加入队列中, 这样的话[0,currentSize)就是上一层,  [currentSize,array.count)就是下一层的所有元素, 然后找到[0,currentSize)中的最大值即可, 然后一次性出队完[0,currentSize)的全部. 这样层次遍历完就完成了.

func largestValues(_ root: TreeNode?) -> [Int] {
    
    if root == nil {
        return []
    }
    // 存放结果
    var result = [Int]()
    // 模拟队列结构
    var array = [TreeNode]()
    // 把根节点加入队列
    array.append(root!)
    
    while array.count > 0 {
        
        var maxValue = Int.min
        // [0,currentSize)是一层的全部数据, 把这些数据的左右孩子加入队列, 同时找出[0,currentSize)中的最大值
        let currentSize = array.count
        for i in 0..<currentSize {
            
            let node = array[i]
            if node.val > maxValue {
                maxValue = node.val
            }
            if node.left != nil {
                array.append(node.left!)
            }
            if node.right != nil {
                array.append(node.right!)
            }
            
        }
        // 一次性移除一层数据
        array.removeFirst(currentSize)
        // 添加该层的最大值到结果中
        result.append(maxValue)
    }

    return result
}

 


其实这个也可以使用中序遍历(前序后续都可以)的, 只不过需要对每一个节点标识下所在的行数.

这个算法最主要的难点就是要知道每层有哪些元素, 我们通过正常的中序遍历, 在遍历每个节点时附加一个层数, 用一个result数组保存每层的最大值,  每个元素遍历时更新result中的值, 遍历完成, result也构建完成.

效率略差一点, 可能是差在递归调用上吧.

func largestValues(_ root: TreeNode?) -> [Int] {
    if root == nil {
        return []
    }

    var result = [Int]()
    
    findMaxValue(root: root, result: &result, level: 0)
    
    print(result)
    return result
}


/// 中序遍历
/// - Parameters:
///   - root: 节点
///   - result: 保存结果的数组
///   - level: 当前节点所在的行
public func findMaxValue(root: TreeNode!, result: inout [Int], level: Int) {

    if root == nil {
        return
    }
    
    // 如果所在行已经有值了,更新值
    if level<result.count {
        result[level] = max(result[level], root.val)
    } else {
        // 这一行还没有值,把这个值认为是最大值
        result.append(root.val)
    }
    
    // 中序遍历左右节点, 同时使行数增加
    findMaxValue(root: root.left, result: &result, level: level+1)
    findMaxValue(root: root.right, result: &result, level: level+1)


}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值