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