一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
一.题目:
199. 二叉树的右视图 给定一个二叉树的 根节点
root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
示例 2:
输入: [1,null,3]
输出: [1,3]
示例 3:
输入: []
输出: []
提示:
- 二叉树的节点个数的范围是
[0,100] -100 <= Node.val <= 100
二、思路分析:
这道题是我今天面试字节碰到的一道题,其实看题目的时候没有做到仔细审题导致了解题思路很模糊,刚开始是想利用DFS递归完成题目的,但是还是改成BFS层次遍历思路更加的清晰,所以这道题我会分为两种思路进行理解。
第一种就是BFS层次遍历,我简化了我面试所写的代码,首先还是把root放入数组中进行循环判断,只要visited数组里面有值的话循环就不会停止代表层次遍历还未结束,每次进入循环都需要记录一下最开始的节点值,随后判断数组值的总数,即每一层的节点都会放入数组中,每次一个大循环完就会进入下一层,因为本题目是要求右视图,所以我们需要每次首先添加右子树的节点,每次循环上一层结束后添加我们存储的最开始的值存入结果集即可完成答案。
第二种就是DFS递归的解法,我们只需要记录深度depth,然后先遍历右子树,每次递归判断当前的结果集长度是否小于depth,如果小于的话我们就清除这一层还没有记录值,将当前的节点值添加至结果集即可,在后序遍历要更新depth值,否则会造成错误。
三、代码:
1.BFS版本
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var rightSideView = function(root) {
let res = []
if(root == null)return res
let visited = [root]
while(visited.length){
let len = visited.length
//记录一下最开始的也就是右视可以看到的
let last = visited[0]
for(let i=0 ; i<len ; i++){
let cur = visited.shift()
if(cur.right != null) visited.push(cur.right)
if(cur.left != null) visited.push(cur.left)
}
res.push(last.val)
}
return res
};
2.DFS版本
var rightSideView = function(root) {
let res = []
let depth = 0
function traverse(root){
if(root == null) return
//前序遍历位置
depth++
//每一层都应该只有一个放入结果集中,如果小于depth值就说明这一层还没有记录值
if(res.length < depth){
res.push(root.val)
}
traverse(root.right)
traverse(root.left)
//后序遍历位置,即离开
depth--
}
traverse(root)
return res
};
四、总结:
今天的面试算法题总体下来说还是比较经典的,如果仔细理解题目的话,早稍加思考就应该能够快速想到利用
层次遍历或者DFS来求解问题,所以总结下来遇事需要冷静。