#include <functional>
#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型vector 先序遍历
     * @param zhongxu int整型vector 中序遍历
     * @return int整型vector
     */
    vector<int> solve(vector<int>& xianxu, vector<int>& zhongxu) {
        vector<int> result(10000);
        int maxlayer = 0;
        function<void(int, int, int, int, int)> dfs = [&](int xl, int xr, int zl, int zr, int layer) -> void {
            if (xl > xr) {
                return;
            }
            maxlayer = max(maxlayer, layer);
            int base = xianxu[xl];
            result[layer] = base;
            int zm = zl;
            while (zhongxu[zm] != base) {
                ++zm;
            }
            dfs(xl + 1, xl + zm - zl, zl, zm - 1, layer + 1);
            dfs(xl + zm - zl + 1, xr, zm + 1, zr, layer + 1);
        };
        dfs(0, xianxu.size() - 1, 0, zhongxu.size() - 1, 0);
        result.resize(maxlayer + 1);
        return result;
    }
};

思路:把这个问题分成两部分。

第一部分:根据先序和中序构造二叉树。有一道原题,直接递归构造即可。

第二部分:计算二叉树的右视图。

* 先序遍历:中-左-右,同时记录当前遍历的深度。

* 数组记录右视图,下标表示深度,下标上的元素表示该深度的最右元素。

* 因为先序遍历,所以对于数组中每个位置(相同深度的节点),树中左边的元素会被右边的元素覆盖,最后一定会得到最右元素。

结合:

* 第一部分实际上就是一个先序遍历的过程。(先找到根节点,再根据根节点区分开左右子树,然后对左右子树递归)

* 所以,在第一部分找到根节点时,记录到数组中的对应位置即可。