【牛客网-名企高频面试题】NC136 输出二叉树的右视图
输出二叉树的右视图
题目描述
请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
示例1
输入
[1,2,4,5,3],[4,2,5,1,3]
返回值
[1,3,5]
解题思路
可以先做这题:105. 从前序与中序遍历序列构造二叉树
从前序遍历确定根节点,然后再去中序遍历中找到左右子树
构建出二叉树后,使用队列存储节点,进行层序遍历二叉树,先左后右,用list记录每层最后出队的元素
其中递归版本的层序遍历:
public int[] dfs1(TreeNode root){
ArrayList<Integer> list = new ArrayList<Integer>(10);
rightSideView(root,list,0);
return list.stream().mapToInt(Integer::valueOf).toArray();
}
private void rightSideView(TreeNode root, ArrayList<Integer> list, int depth) {
if (root == null) {
return;
}
if (depth == list.size()) {
list.add(root.val);
}
rightSideView(root.right, list, depth+1);
rightSideView(root.left, list, depth+1);
}
非递归版本的层序遍历:
public int[] dfs(TreeNode root){
if(root == null)
return null;
List<Integer> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
for(TreeNode tmp = root; !queue.isEmpty();){
//此处注意循环中queue.size()在变
for(int size = queue.size();size > 0;size--){
tmp = queue.poll();
if(tmp.left != null)
queue.offer(tmp.left);
if(tmp.right != null)
queue.offer(tmp.right);
}
//添加每层最右元素
list.add(tmp.val);
}
return list.stream().mapToInt(Integer::valueOf).toArray();
}
最后整合代码:
/**
* Copyright (C), 2019-2021
* author candy_chen
* date 2021/5/12 10:07
*
* @Classname NC_136
* Description: 输出二叉树的右视图
*/
import java.util.*;
/**
*
*/
public class NC_136 {
class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int val){
this.val = val;
}
}
public int[] solve(int[] xianxu,int[] zhongxu){
TreeNode root = reBuild(xianxu,zhongxu);
return dfs(root);
}
//层序遍历,广度优先dfs
//队列存储节点,先左后右。list记录每层最后出队元素
private int[] dfs(TreeNode root) {
if (root == null){
return null;
}
List<Integer> list = new ArrayList<>();
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
list.add(queue.peekLast().val);
for (int i = 0; i < size; i++) {
TreeNode curr = queue.poll();
if (curr.left != null){
queue.offer(curr.left);
}
if (curr.right != null){
queue.offer(curr.right);
}
}
}
return list.stream().mapToInt(Integer::valueOf).toArray();
}
//先确定根节点,中序遍历确定左右子树
private TreeNode reBuild(int[] xianxu, int[] zhongxu) {
if (xianxu == null || xianxu.length == 0){
return null;
}
int val = xianxu[0],pos = 0,len = xianxu.length;
TreeNode root = new TreeNode(val);
//找到中序数组根节点位置
for (;pos < len;pos++){
if (zhongxu[pos] == val)
break;
}
root.left = reBuild(Arrays.copyOfRange(xianxu,1,pos+1),
Arrays.copyOfRange(zhongxu,0,pos));
root.right = reBuild(Arrays.copyOfRange(xianxu,pos+1,len),
Arrays.copyOfRange(zhongxu,pos+1,len));
return root;
}
}