class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 求二叉树的右视图 * @param preOrder int整型vector 先序遍历 * @param inOrder int整型vector 中序遍历 * @return int整型vector */ vector<int> res; struct node{ node* left=nullptr; node* right=nullptr; int val=0; node(int _val):val(_val){} node(int _val, node* _left, node* _right):left(_left),right(_right),val(_val){} }; //先序遍历得到根节点,然后在中序遍历中找到根节点、左子树、右子树,返回一层中最右的子树的根节点 vector<int> solve(vector<int>& preOrder, vector<int>& inOrder) { if(preOrder.empty())return {}; node* root = rebuild(preOrder, inOrder, 0, preOrder.size()-1, 0, inOrder.size()-1); queue<node*> q; q.push(root); int size = 1; while(!q.empty()){ res.push_back(q.front()->val); //放下一层右边第一个节点 int new_size = 0; while(size > 0){ //排出当前层,放入下一层 node* temp = q.front();q.pop(); if(temp->right != nullptr){ q.push(temp->right); new_size++; } //非空的放入 if(temp->left != nullptr){ q.push(temp->left); new_size++; } --size; } size = new_size; } return res; } //重建二叉树,前序遍历数组的头一个是根节点,在中序遍历中找到根节点,通过下标计算出左右子树的大小,然后确定前序遍历数组中的左子树和右子树的范围,递归得对子树划分; node* rebuild(vector<int>& preOrder, vector<int>& inOrder, int pre_front_idx, int pre_back_idx, int in_front_idx, int in_back_idx){ if(pre_front_idx > pre_back_idx){ return nullptr; } if(pre_front_idx == pre_back_idx){ return new node(preOrder[pre_back_idx]); } auto it = find(inOrder.begin()+in_front_idx, inOrder.begin()+in_back_idx, preOrder[pre_front_idx]); //string有find方法找到下标:s.find(num); vector没有。只有函数,返回迭代器; int root_idx = distance(inOrder.begin(), it); //找到下标 int left_sz = root_idx - in_front_idx; //左子树有多少个 int right_sz = in_back_idx - root_idx; //右子树有多少个 node* left_node = rebuild(preOrder, inOrder, pre_front_idx+1, pre_front_idx +left_sz , in_front_idx, root_idx-1); node* right_node = rebuild(preOrder, inOrder, pre_back_idx-right_sz+1, pre_back_idx, root_idx+1, in_back_idx); return new node(*it, left_node, right_node); } };