import java.util.*; public class Solution { private static class TreeNode { int val; TreeNode left; TreeNode right; public TreeNode(int val) { this.val = val; } } /** * @param preorder 根左右 * @param inorder 左根右 * @return 右视图数组 */ public int[] solve (int[] preorder, int[] inorder) { TreeNode root = rebuild(preorder,inorder,0,preorder.length-1,0,inorder.length-1); ArrayList<Integer> res = new ArrayList<>(); getRightView(root,res); //将结果转换为数组返回 int[] ret = new int[res.size()]; for (int i = 0; i < res.size(); i++) { ret[i] = res.get(i); } return ret; } /** * 递归重建二叉树 * @param preorder 先序遍历数组 * @param inorder 中序遍历数组 * @param pStart 先序中开始下标 * @param pEnd 先序中结束下标 * @param iStart 中序中开始下标 * @param iEnd 中序中结束下标 * @return 根节点 */ private TreeNode rebuild(int[] preorder, int[] inorder, int pStart, int pEnd, int iStart, int iEnd) { //终止条件 if (pEnd < pStart || iEnd < iStart) { return null; } //构造根节点 TreeNode root = new TreeNode(preorder[pStart]); //在中序中找到根节点对应的下标 //因为题目中规定输入合法且无重复值,则在中序遍历中一定可以找到根节点对应的下标 int index = iStart; while (inorder[index] != preorder[pStart]) { index++; } //递归构建左子树和右子树 root.left = rebuild(preorder,inorder,pStart+1,pStart+index-iStart,iStart,index-1); root.right = rebuild(preorder,inorder,pStart+index-iStart+1,pEnd,index+1,iEnd); return root; } /** * 以根右左的顺序遍历,同时通过全局变量 deep 记录深度,每次达到一个新的深度的时候将该结点的 val 放在 res 中 * @param root 根节点 * @param res 记录遍历结果的链表 */ private int deep = 0; private void getRightView(TreeNode root, ArrayList<Integer> res) { if (root == null) { return; } //维护当前深度 deep++; //判断一下当前是不是到达了这个树新的深度 //因为没到一个新的深度,我们都会往 res 中加一个元素 //因此我们通过 res 和 deep 的关系来判断 if (deep > res.size()) { res.add(root.val); } //继续遍历 getRightView(root.right,res); getRightView(root.left,res); //维护深度 deep--; return; } }