算法学习第十天

176 阅读1分钟

  周末时间比较充足,来一题中等难度的题目。leetcode的第515题-在每个树行中找最大值,是一题关于二叉树的题目。至于二叉树遍历平时讨论的比较多的深度优先遍历和广度优先遍历,今天的解法也会从这两种遍历方式进行入手。先看题目:

您需要在二叉树的每一行中找到最大的值。
输入: 

          1
         / \
        3   2
       / \   \  
      5   3   9 

输出: [1, 3, 9]

  首先是广度优先遍历解法 这题要求的是输出每一行的最大值,而不是每一行的所有值:

var largestValues = function(root) {
    if (!root) return []
    let res = []
    let queue = [root]
    while (queue.length > 0) {
        const length = queue.length
        let max;
        for (let i = 0; i < length; i++) {
            const item = queue.shift()
            if (!max && max !== 0) max = item.val
            if (item.val > max) max = item.val
            if (item.left) queue.push(item.left)
            if (item.right) queue.push(item.right)

        }
        res.push(max)
    }
    return res
};

  大概思路就是当遍历到当前层时,加多一个循环,把这一层的所有元素马上取出进行遍历对比。同时把下一层的元素给放队伍中,这里需要注意的地方就是,要在遍历前把queue的长度也提前读取并缓存;否则在循环遍历中插入新元素时,会导致读取新的长度而引发错误。
  然后再来深度优先解法 这里是用了递归来实现,并且把当前处于哪一层以参数形式给传下去,方便后续的层数对比:

var largestValues = function(root) {
    if (!root) return []
    const res = []
    dfs(root, res, 0)
    function dfs(root, res, level) {
        if ((!res[level] && res[level] !== 0 ) || res[level] < root.val) res[level] = root.val;
        if (root.left) dfs(root.left, res, level + 1)
        if (root.right) dfs(root.right, res, level + 1)
    }
    return res
};

  思路就是通过递归一层一层的遍历下去,直到触碰边界终止才进行后续逻辑。比如上面的情况,会先把左子树给遍历完,再进行右子树的遍历。并且遍历的过程是会一层一层地把子孙后代给遍历完,直到没有后代了再结束。注意要加上终止条件,只有节点的子节点为真才进行遍历后代。
  总结:首先要理解好深度优先遍历和广度优先遍历的区别,以及实现的代码逻辑。再对其进行修改,以达到题目的要求