class Solution {
  public:
    struct TreeNode {
        int val;
        TreeNode* left;
        TreeNode* right;
        TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };

    vector<int> solve(vector<int>& preOrder, vector<int>& inOrder) {
        if (preOrder.empty() || inOrder.empty()) return {};

        // 构建二叉树
        TreeNode* root = buildTree(preOrder, 0, preOrder.size() - 1,
                                   inOrder, 0, inOrder.size() - 1);

        // 获取右视图
        return getRightView(root);
    }

  private:
    TreeNode* buildTree(vector<int>& preOrder, int preStart, int preEnd,
                        vector<int>& inOrder, int inStart, int inEnd) {
        if (preStart > preEnd || inStart > inEnd) return nullptr;

        // 前序遍历的第一个节点是根节点
        int rootVal = preOrder[preStart];
        TreeNode* root = new TreeNode(rootVal);

        // 在中序遍历中找到根节点的位置
        int rootIndex = inStart;
        while (rootIndex <= inEnd && inOrder[rootIndex] != rootVal) {
            rootIndex++;
        }

        // 计算左子树的节点个数
        int leftSize = rootIndex - inStart;

        // 递归构建左右子树
        root->left = buildTree(preOrder, preStart + 1, preStart + leftSize,
                               inOrder, inStart, rootIndex - 1);
        root->right = buildTree(preOrder, preStart + leftSize + 1, preEnd,
                                inOrder, rootIndex + 1, inEnd);

        return root;
    }

    vector<int> getRightView(TreeNode* root) {
        if (!root) return {};

        vector<int> result;
        queue<TreeNode*> q;
        q.push(root);

        while (!q.empty()) {
            int levelSize = q.size();

            for (int i = 0; i < levelSize; i++) {
                TreeNode* node = q.front();
                q.pop();

                // 如果是当前层的最后一个节点,加入结果
                if (i == levelSize - 1) {
                    result.push_back(node->val);
                }

                // 将子节点加入队列
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
        }

        return result;
    }
};

1.根据前序和中序遍历重建二叉树
前序遍历的第一个元素是根节点
在中序遍历中找到根节点,左边是左子树,右边是右子树
递归构建左右子树

2.获取二叉树的右视图
使用层次遍历,记录每一层的最后一个节点
或者使用DFS,优先访问右子树

class Solution {
public:
    struct TreeNode {
        int val;
        TreeNode *left;
        TreeNode *right;
        TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };

    vector<int> solve(vector<int>& preOrder, vector<int>& inOrder) {
        if (preOrder.empty() || inOrder.empty()) return {};
        
        // 构建二叉树
        TreeNode* root = buildTree(preOrder, 0, preOrder.size() - 1, 
                                  inOrder, 0, inOrder.size() - 1);
        
        // 使用DFS获取右视图
        return getRightViewDFS(root);
    }

private:
    TreeNode* buildTree(vector<int>& preOrder, int preStart, int preEnd,
                       vector<int>& inOrder, int inStart, int inEnd) {
        if (preStart > preEnd || inStart > inEnd) return nullptr;
        
        // 前序遍历的第一个节点是根节点
        int rootVal = preOrder[preStart];
        TreeNode* root = new TreeNode(rootVal);
        
        // 在中序遍历中找到根节点的位置
        int rootIndex = inStart;
        while (rootIndex <= inEnd && inOrder[rootIndex] != rootVal) {
            rootIndex++;
        }
        
        // 计算左子树的节点个数
        int leftSize = rootIndex - inStart;
        
        // 递归构建左右子树
        root->left = buildTree(preOrder, preStart + 1, preStart + leftSize,
                              inOrder, inStart, rootIndex - 1);
        root->right = buildTree(preOrder, preStart + leftSize + 1, preEnd,
                               inOrder, rootIndex + 1, inEnd);
        
        return root;
    }
    
    vector<int> getRightViewDFS(TreeNode* root) {
        vector<int> result;
        dfs(root, 0, result);
        return result;
    }
    
    void dfs(TreeNode* node, int depth, vector<int>& result) {
        if (!node) return;
        
        // 如果当前深度等于结果数组的大小,说明这是该层第一个被访问的节点
        // 由于我们先访问右子树,所以这个节点就是右视图中的节点
        if (depth == result.size()) {
            result.push_back(node->val);
        }
        
        // 先递归右子树,再递归左子树
        dfs(node->right, depth + 1, result);
        dfs(node->left, depth + 1, result);
    }
};