难度:中等
频次:91
题目:
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
解题思路:
- BFS 广度优先搜索----其实像一些层序遍历,都优先BFS
- DFS 深度优先搜索----先中后序都使用DFS
BFS
跟这道题类似的还有
102 二叉树的层序遍历
103 二叉树的锯齿形层序遍历
注意:
- 用一个队列辅助,我这里用的是双端队列
- 用一个n标记每次队列一开始有几个元素
- poll出元素的时候,判断i是否是之前最后一个元素,是的话,添加到res结果列表里
- queue添加元素是add方法,删除元素是用poll元素
- new ArrayDeque(); 这里不用尖括号<>();
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> rightSideView(TreeNode root) {
//层序遍历---使用一个deque存储下一层的节点,
//然后遍历下次拿出这些节点的时候顺便把它的子节点再放入deque里
List<Integer> res=new ArrayList<>();
//结构要选好,使用一个队列辅助
Queue<TreeNode> queue=new ArrayDeque();
//判断根节点是否为空
if(root!=null) queue.add(root);
while(queue.size()>0){
//用n做标记每次需要poll几个
int n=queue.size();
for(int i=0;i<n;i++){
TreeNode temp= queue.poll();
//要判空
if(temp.left!=null) queue.add(temp.left);
if(temp.right!=null) queue.add(temp.right);
//因为只要最右边的,所以等到是最后一个时,即n-1是把值添加到res
//其实不管什么方法的遍历,只是这个条件不同而已
//普通遍历————不需要条件,每次都添加
//Z形遍历----用一个m记住深度,判断m%2做不同的操作,一个头插一个尾插
//右视图----只要最后一个
if(i==n-1) {
res.add(temp.val);
}
}
}
return res;
}
}
DFS
跟这道题类似的有很多,大多数都是必须多写一个DFS递归函数的。下面几道题的递归做法都类似
- 94 二叉树的中序遍历
- 144 二叉树的前序遍历
- 145 二叉树的后序遍历
注意
- 改变遍历顺序,先 中间节点—右边子节点—左边子节点
- 用一个东西做标记,相当于遍历的是每层 最后一个的时候,添加到res里
- 这里是用深度和res的元素数量做标记,如果相等,说明是刚进入新的一层里,而且是最右边的元素 - depth++的位置必须要放在下一层DFS的前面
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res=new ArrayList<Integer>();
int depth=0;
DFS(res,root,0);
return res;
}
public void DFS(List<Integer> res,TreeNode root,int depth){
if(root==null) return;
//因为只要最后一个,所以需要判断
//因为是先 中间节点---右边子节点---左边子节点
//当深度==res大小的时候,说明这一层还没遍历,当第一次进入这一层的时候,
//这个时候遍历的就是右视图的节点
if(depth==res.size())
{
res.add(root.val);
}
//必须放前面,如果放在DFS后面,那深度就不会增加了
//只能够是在要进入下一层的时候,先+1
depth++;
//必须先遍历右边的
DFS(res,root.right,depth);
DFS(res,root.left,depth);
}
}