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);
}
};