首页 > 试题广场 >

输出二叉树的右视图

[编程题]输出二叉树的右视图
  • 热度指数:47723 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图

数据范围:
要求: 空间复杂度 ,时间复杂度

如输入[1,2,4,5,3],[4,2,5,1,3]时,通过前序遍历的结果[1,2,4,5,3]和中序遍历的结果[4,2,5,1,3]可重建出以下二叉树:

所以对应的输出为[1,3,5]。
示例1

输入

[1,2,4,5,3],[4,2,5,1,3]

输出

[1,3,5]

备注:
二叉树每个节点的值在区间[1,10000]内,且保证每个节点的值互不相同。
/**1先构造二叉树
   2程序遍历
*/
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
public     List<Integer>list=new ArrayList<Integer>();
    public int[] solve (int[] xianxu, int[] zhongxu) {
        // write code here
        TreeNode head =dfs(xianxu,zhongxu);
        getRightList(head);
        int[]a=new int[list.size()];
        for(int i=0;i<list.size();i++){
            a[i]=list.get(i);
        }
       
        return a;
    }
    
    public TreeNode dfs(int[]xianxu,int[] zhongxu ){
        if(xianxu.length==0||zhongxu.length==0){
            return null;
        }
       
        TreeNode head= new TreeNode(xianxu[0]);
        if(xianxu.length==1||zhongxu.length==1){
            return head;
        }
       for(int i=0;i<zhongxu.length;i++){
           if(zhongxu[i]==xianxu[0]){
               head.left=dfs(Arrays.copyOfRange(xianxu,1,i+1),Arrays.copyOfRange(zhongxu,0,i));
               head.right=dfs(Arrays.copyOfRange(xianxu,i+1,xianxu.length),Arrays.copyOfRange(zhongxu,i+1,zhongxu.length));
           }
       }
       return head;
    }
    public void getRightList(TreeNode root){
      Queue<TreeNode> q=new LinkedList<TreeNode>();
        q.offer(root);
        while(!q.isEmpty()){
            int mount=q.size();
            for(int i=0;i<mount;i++){
                if(q.peek().left!=null)
                    q.offer(q.peek().left);
                if(q.peek().right!=null)
                    q.offer(q.peek().right);
                if(i==mount-1){
                    list.add(q.poll().val);
                }  else{
                    q.poll();
                } 
                
            }
              
        }
    }
 
}

发表于 2022-03-07 22:20:24 回复(0)
不需要构造树。用一个全局的字典来存储遍历过程中每层的节点。
这样,最后将字典排序后,输出每层节点的最后一个即可。
class Solution:
    def __init__(self):
        self.level = defaultdict(list)

    def solve(self , xianxu , zhongxu ):
        # write code here
        if len(xianxu) == 0:
            return []
        if len(xianxu) == 1:
            return xianxu
        self.reverse(xianxu, zhongxu, 0)
        res = []
        level = sorted(self.level.items())
        for l in level:
            res.append(l[1][-1])
        return res
    
    def reverse(self, xianxu, zhongxu, level):
        if len(xianxu) == 0:
            return
        if len(xianxu) == 1:
            self.level[level].append(xianxu[0])
            return
        root = xianxu[0]
        index = zhongxu.index(root)
        self.level[level].append(root)
        self.reverse(xianxu[1:index+1], zhongxu[:index], level+1)
        self.reverse(xianxu[index+1:], zhongxu[index+1:], level+1)

发表于 2021-08-04 12:15:20 回复(0)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 * 求二叉树的右视图
 * @param xianxu int整型一维数组 先序遍历
 * @param zhongxu int整型一维数组 中序遍历
 * @return int整型一维数组
 */
// 1、创建节点类型
function TreeNode(x) {
   this.val = x;
   this.left = null;
   this.right = null;
}
// 2、创建二叉树
function buildTree(xianxu, zhongxu) {
    if(xianxu.length === 0 || zhongxu.length === 0) {
        return null;
    }
    let root = new TreeNode(xianxu[0]);
    let index = zhongxu.indexOf(root.val);
    let leftPre = xianxu.slice(1, index + 1);
    let leftVin = zhongxu.slice(0, index);
    root.left = buildTree(leftPre, leftVin);
    let rightPre = xianxu.slice(index + 1);
    let rightVin = zhongxu.slice(index + 1);
    root.right = buildTree(rightPre, rightVin);
    return root;
}
// 3、输出二叉树的右视图
function printRight(root) {
    if(!root) {
        return [];
    }
    let res = [];
    let queue = [root];
    let index = 0;
    while(queue.length) {
        let len = queue.length;
        for(let i=0; i<len; i++) {
            let node = queue.shift();
            if(i === (len - 1)) {
                res[index] = node.val;
                index++;
            }
            if(node.left) {
                queue.push(node.left);
            }
            if(node.right) {
                queue.push(node.right);
            }
        }
    }
    return res;
}
function solve( xianxu ,  zhongxu ) {
    let root = buildTree(xianxu, zhongxu);
    let rightView = printRight(root);
    return rightView;
}
module.exports = {
    solve : solve
};

发表于 2021-07-20 15:09:15 回复(0)
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    public int[] solve (int[] xianxu, int[] zhongxu) {
        // write code here
        TreeNode root = reCons(xianxu, zhongxu);
        return bfs(root);
    }
    public TreeNode reCons (int[] xianxu, int[] zhongxu) {
        if(xianxu == null || xianxu.length == 0) return null;
        int val = xianxu[0], position = 0, len = xianxu.length;
        TreeNode root = new TreeNode(val);
        for(position = 0; position < len; position++) {
            if(zhongxu[position] == val) break;
        }
        root.left = reCons(Arrays.copyOfRange(xianxu, 1, position + 1), Arrays.copyOfRange(zhongxu, 0 , position));
        root.right = reCons(Arrays.copyOfRange(xianxu, position + 1, len), Arrays.copyOfRange(zhongxu,position + 1, len));
        return root;       
    }
    public int[] bfs (TreeNode root) {
        if(root == null) return null;
        List<Integer> ls = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        int temp = 0;
        while(!q.isEmpty()) {
            int size = q.size();
            while(size > 0) {
                TreeNode t = q.poll();
                if(t.left != null) q.add(t.left);
                if(t.right != null) q.add(t.right);
                size--;
                temp = t.val;
            }
            ls.add(temp);
        }
        int[] res = new int[ls.size()];
        for(int i = 0; i < res.length; i++) {
            res[i] = ls.get(i);
        }
        return res; 
    }
}

发表于 2021-05-31 09:45:56 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    public int[] solve (int[] xianxu, int[] zhongxu) {
        if (xianxu.length == 0 || zhongxu.length == 0){
            return null;
        }
        List<TreeNode> list = new ArrayList<>();
        TreeNode root = build(xianxu, zhongxu);

        //队列交换
        //指针cur永远指向不为空的队列
        Queue<TreeNode> cur = new LinkedList<>();

        //指针temp永远指向空的队列
        Queue<TreeNode> temp = new LinkedList<>();
        cur.offer(root);

        //cur指向的队列进行出队操作,temp指向的队列进行入队操作
        while (!cur.isEmpty()){
            TreeNode poll = cur.poll();
            if (cur.size() == 0){
                list.add(poll);
            }
            if (poll.left != null){
                temp.offer(poll.left);
            }
            if (poll.right != null){
                temp.offer(poll.right);
            }
            if (cur.isEmpty()){
                Queue<TreeNode> t = cur;
                cur = temp;
                temp = t;
            }
        }
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i).val;
        }
        return result;
    }
    private TreeNode build(int[] pre, int[] in){
        if (pre.length == 0 || in.length == 0){
            return null;
        }

        TreeNode root = new TreeNode(pre[0]);

        if (pre.length == 1 || in.length == 1){
            return root;
        }

        int rootIndex = 0;
        for (int i = 0; i < in.length; i++) {
            if (in[i] == root.val){
                rootIndex = i;
                break;
            }
        }
        root.left =
                build(Arrays.copyOfRange(pre, 1, rootIndex+1), Arrays.copyOfRange(in, 0, rootIndex));
        root.right =
                build(Arrays.copyOfRange(pre,rootIndex+1,pre.length),Arrays.copyOfRange(in,rootIndex+1,in.length));

        return root;
    }
}

发表于 2021-04-30 20:25:28 回复(0)
function solve( xianxu ,  zhongxu ) {
    const root = buildTree(xianxu, zhongxu);
    const rightView = getRightView(root);
    return rightView;
}
function buildTree(xianxu, zhongxu) {
    if (xianxu.length === 0) return null;
    const root = new TreeNode(xianxu[0]);
    const index = zhongxu.indexOf(root.val);
    const lefts = zhongxu.slice(0, index);
    const rights = zhongxu.slice(index + 1);
    root.left = buildTree(xianxu.slice(1, lefts.length + 1), lefts);
    root.right = buildTree(xianxu.slice(lefts.length + 1), rights);
    return root;
}
function getRightView(root) {
    const res = [];
    let stack = [root];
    while (stack.length) {
        const rowLen = stack.length;
        const newStack = [];
        for (let i = 0; i < rowLen; i++) {
            const node = stack[i];
            if (i === stack.length - 1) res.push(node.val);
            if (node.left) newStack.push(node.left);
            if (node.right) newStack.push(node.right);
        }
        stack = newStack;
    }
    return res;
}

发表于 2021-04-08 19:27:55 回复(0)
python
1、重构二叉树
2、输出右视图
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def solve(self , preorder , inorder ):
        # 递归函数,用于返回当前根结点并求其左右孩子
        def myBuildTree(preorder_left: int, preorder_right: int, inorder_left: int, inorder_right: int):
            if preorder_left > preorder_right:
                return None
            
            # 前序遍历中的第一个节点就是根节点
            preorder_root = preorder_left
            # 在中序遍历中定位根节点
            inorder_root = index[preorder[preorder_root]]
            
            # 先把根节点建立出来
            root = TreeNode(preorder[preorder_root])
            # 得到左子树中的节点数目
            size_left_subtree = inorder_root - inorder_left
            # 递归地构造左子树,并连接到根节点
            # 先序遍历中从 左边界+1 开始的 size_left_subtree 个元素就对应了中序遍历中从 左边界 开始到 根节点定位-1 的元素
            root.left = myBuildTree(preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1)
            # 递归地构造右子树,并连接到根节点
            # 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
            root.right = myBuildTree(preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right)
            return root
        
        n = len(preorder)
        # 构造哈希映射,帮助我们快速定位根节点
        index = {element: i for i, element in enumerate(inorder)}
        bitree = myBuildTree(0, n - 1, 0, n - 1)
        
        # 开始求右视图,每层遍历到最后一个元素时,队尾入队一个-1,标记最后一个元素要输出
        queue = [bitree, -1]
        cur = -1
        res = list()
        while len(queue) > 1:
            last = cur
            cur = queue.pop(0)
            if cur == -1:
                if type(last) == TreeNode:
                    res.append(last.val)
                queue.append(-1)
            else:
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
        res.append(cur.val)  # 不知怎的,反正最终一个元素需要手动append
        return res


发表于 2021-03-31 15:36:27 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    HashMap<Integer,Integer> inorder = new HashMap<>();
    int[] pre;
    HashMap<Integer,Integer> res = new HashMap<>();
    public int[] solve (int[] xianxu, int[] zhongxu) {
        this.pre = xianxu;
        for (int i = 0; i < xianxu.length; i++) {
            inorder.put(zhongxu[i],i);
        }
        run(0,xianxu.length - 1,0,0);
        int[] result = new int[res.size()];
        for (int i = 0; i < result.length; i++) {
            result[i] = res.get(i);
        }
        return result;
    }
    /*
      中序遍历的左右两端l、r
      先序遍历的根节点
      当前递归的二叉树层数
      
      由于hashmap的key不能重复,所以如果是同一层的数据就只会保存最后一个数据也就是从右往左看的结果
      
    
    */
    public void run(int l,int r,int root,int level){
        if (r < l){
            return;
        }
        int t = inorder.get(pre[root]);
        System.out.println(pre[root]);
        res.put(level,pre[root]);
        run(l,t - 1,root + 1,level + 1);
        run(t + 1,r,root + t - l + 1,level + 1);
    }

}

发表于 2021-12-30 11:07:59 回复(0)
思想:递归,dfs
做法:
  • 先将根节点的值放入list,即put(level, rootVal)(如果是最左侧节点,就要用add,因为遍历到了一个新的level), level表示当前树(or子树)的根结点在第几层
  • 然后将左子树看作一棵新的树,但注意要将level + 1, 因为已经到了下一层。
  • 对左子树操作完之后再操作右子树,这样的话,进行put(level, rootVal)运算时,同一level中,右边节点可以覆盖左边节点的值,最终得到的就是右视图!
import java.util.*;

public class Solution {
    private List<Integer> res;
    private int[] myPre;
    private int[] myIn;
    private int len;
    public int[] solve (int[] xianxu, int[] zhongxu) {
        res = new ArrayList<>();
        myPre = xianxu;
        myIn = zhongxu;
        len = xianxu.length;
        dfs(0, len - 1, 0, len - 1, 0);
        int[] ans = new int[res.size()]; // 转成数组返回
        for (int i = 0; i < res.size(); i++) {
            ans[i] = res.get(i);
        }
        return ans;
    }
    
    private void dfs(int start1, int end1, int start2, int end2, int level) {
        if (start1 > end1) {
            return;
        }
        int rootVal = myPre[start1]; // 当前根结点
        if (res.size() <= level) { // 说明当前是最左节点,只能add,不能覆盖
            res.add(rootVal);
        }
        else {
            res.set(level, rootVal); // 覆盖同一level中之前记录过的节点,最终保留的就是每一level的最右节点
        }
        for (int i = 0; i < len; i++) {
            if (myIn[i] == rootVal) { // 递归调用
                dfs(start1 + 1, start1 + i - start2, start2, i - 1, level + 1);
                dfs(start1 + i - start2 + 1, end1, i + 1, end2, level + 1);
                break;
            }
        }
    }
}

发表于 2021-01-18 09:41:00 回复(5)
//先构建出二叉树,再打印出右视图
class Solution {
public:
    vector<int> ans;
    vector<int> solve(vector<int> &preorder, vector<int> &inorder) {
        int presize = preorder.size();
        int insize = inorder.size();
        if (presize != insize || presize == 0 || insize == 0)
            return ans;
        auto head = ReconstructTree(preorder, inorder, 0, presize - 1, 0, insize - 1);
        rightTree(head);
        return ans;
    }
    void rightTree(TreeNode *head) {
        queue<TreeNode *> q;
        q.push(head);
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                auto tmp = q.front();
                q.pop();
                if (tmp->left) q.push(tmp->left);
                if (tmp->right) q.push(tmp->right);
                if (i == size - 1) ans.push_back(tmp->val);
            }
        }
    }
    TreeNode *ReconstructTree(vector<int> &preorder, vector<int> &inorder, int pl, int pr, int il, int ir) {
        auto *root = new TreeNode(preorder[pl]);
        if (pl == pr) return root;
        int index = 0;
        for (int i = il; i <= ir; i++) {
            if (inorder[i] == preorder[pl]) {
                index = i;
                break;
            }
        }
        int ltreelen = index - il;
        int rtreelen = ir - index;
        if (ltreelen > 0) root->left = ReconstructTree(preorder, inorder, pl + 1, pl + ltreelen, il, index - 1);
        if (rtreelen > 0) root->right = ReconstructTree(preorder, inorder, pl + 1 + ltreelen, pr, index + 1, ir);
        return root;
    }
};

发表于 2020-10-22 22:05:19 回复(0)
一开始不知什么叫右视图,还以为 右视图 是 对根节点的 右侧子树的 层次遍历的打印,后来才发现 概念不是这样的,右视图可以这样认为将这棵树放到面前,你去走到这棵树的右面,把你所有能看到的节点打印出来。
以下为代码:
import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     *
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    ArrayList<ArrayList<Integer>> lists = new ArrayList<>();

    public int[] solve(int[] xianxu, int[] zhongxu) {
        // write code here
        lists.add(new ArrayList<Integer>());
        TreeNode root = Go(xianxu, zhongxu);
        Go2(root, 0);
        ArrayList<Integer> list = new ArrayList<>();
        //将二叉树 层次便利的 每层的额最后一个 值存入新的 ArrayList 中 转化为 数组
        for (int i = 0; i < lists.size(); i++) {

            list.add(lists.get(i).get(lists.get(i).size() - 1));

        }
        int result[] = list.stream().mapToInt(Integer::valueOf).toArray();
        return result;
    }

    //此方法用来重建二叉树
    private TreeNode Go(int[] pre, int[] in) {
        if (pre.length == 0 || in.length == 0) {
            return null;
        }
        TreeNode node = new TreeNode(pre[0]);
        for (int i = 0; i < in.length; i++) {
            if (in[i] == pre[0]) {
                node.left = Go(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
                node.right = Go(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
                break;

            }
        }

        return node;
    }

    //此方法用来 二叉树的 层次遍历到 ArrayList<ArrayList<Integer>>中
    private void Go2(TreeNode root, int flag) {
        if (lists.size() < flag + 1) {
            lists.add(new ArrayList<Integer>());
        }
        lists.get(flag).add(root.val);
        if (root.left != null)
            Go2(root.left, flag + 1);
        if (root.right != null)
            Go2(root.right, flag + 1);
    }
}

发表于 2020-12-12 14:31:16 回复(0)

先把树构建出来,在通过队列取出每层的最后一个节点的值
时间复杂度:O(n) 空间复杂度:O(n)

class Solution:
    def tree(self, pre, vin):
        if not pre:
            return None
        root = TreeNode(pre[0])
        tem = vin.index(pre[0])
        root.left = self.tree(pre[1:tem+1], vin[:tem])
        root.right = self.tree(pre[tem+1:], vin[tem+1:])
        return root
    def solve(self , pre: List[int], vin: List[int]) -> List[int]:
        res = []
        root = self.tree(pre, vin)
        q = [root]
        while q:
            n = len(q)
            for i in range(n):
                cur = q.pop(0)
                if i == n-1:
                    res.append(cur.val)
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
        return res
发表于 2022-05-17 16:15:22 回复(0)

不构造树,利用map 直接得出右视图!

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    public int[] solve (int[] xianxu, int[] zhongxu) {
        Map<Integer,Integer> map = new HashMap<>();
        if (xianxu.length == 0 || xianxu.length != zhongxu.length) return new int[0];
        findU(xianxu, zhongxu, 0, xianxu.length - 1, 0, zhongxu.length - 1, map, 0);
        int[] res = new int[xianxu.length];
        int len = 0;
        Integer temp;
        while ((temp = map.get(len)) != null) {
            res[len++] = temp;
        }
        return Arrays.copyOf(res, len);
        // write code here
    }
    
    private void findU(int[] xianxu, int[] zhongxu, int xleft, int xright,
                       int zleft, int zright, Map<Integer, Integer> map, int level) {
        if (xleft > xright || zleft > zright) return;
        int p = xianxu[xleft];
        int i = zleft;
        for (; i <= zright && zhongxu[i] != p; i++);
        // 如果存在则说明构建右节点的时候已经放进去了
        if (!map.containsKey(level))
            map.put(level, p);
        // 先构建右边的结点  i - zleft代表左节点有多少个
        findU(xianxu, zhongxu, xleft + (i - zleft) + 1, xright, i + 1, zright, map, level + 1);
        // 构建左结点
        findU(xianxu, zhongxu, xleft + 1, xleft + (i - zleft), zleft, i - 1, map, level + 1);
    }
}


发表于 2021-05-08 11:29:19 回复(0)
1. 了解前序、中序特性去构建二叉树
先序   [1,i+1)   [i+1,prevLength)
中序   [0,i]     [i+1,middleLength]
2. 利用中间数据结构去存储结果(我们这里用的Map key是树的深度 value是最右的元素)
  public int[] solve(int[] xianxu, int[] zhongxu) {
        TreeNode node = initTreeNode(xianxu, zhongxu);
        Map<Integer, Integer> deep = new HashMap<>();
        resolve(node, 0, deep);
        int[] res = new int[deep.size()];
        for (int i = 0; i < deep.size(); i++) {
            res[i] = deep.get(i);
        }
        return res;
    }

    private void resolve(TreeNode node, Integer deepth, Map<Integer, Integer> deep) {
        if (node == null) {
            return;
        }
        deep.put(deepth, node.val);
        resolve(node.left, deepth + 1, deep);
        resolve(node.right, deepth + 1, deep);
    }

    private TreeNode initTreeNode(int[] prev, int[] middle) {
        //[1,2,4,5,3],[4,2,5,1,3]
        if (prev.length == 0) {
            return null;
        }
        int root = prev[0];
        TreeNode node = new TreeNode(root);
        int i = 0;
        for (; i < middle.length; i++) {
            if (middle[i] == root) {
                break;
            }
        }
        // 左子树 [1,i-1]
        int[] leftMid = Arrays.copyOfRange(middle, 0, i);
        int[] leftPre = Arrays.copyOfRange(prev, 1, i + 1);
        node.left = initTreeNode(leftPre, leftMid);


        // 右子树[i+1,middle.length]
        int[] rightMid = Arrays.copyOfRange(middle, i + 1, prev.length);
        int[] rightPrev = Arrays.copyOfRange(prev, i + 1, prev.length);
        node.right = initTreeNode(rightPrev, rightMid);
        return node;
    }


发表于 2022-02-10 18:03:02 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型vector 先序遍历
     * @param zhongxu int整型vector 中序遍历
     * @return int整型vector
     */
    
    TreeNode* reBuild(vector<int>& pre, vector<int>& in)
    {
        int len = pre.size();
        if(!len)
        {
            return NULL;
        }
        int root_val = pre[0];
        TreeNode* root = new TreeNode(root_val);
        int left_len = -1;
        for(int i = 0; i < len; i++)
        {
            if(in[i] == root_val)
            {
                left_len = i;
                break;
            }
        }
        vector<int> pre_left(pre.begin() + 1, pre.begin() + 1 + left_len);
        vector<int> pre_right(pre.begin() + 1 + left_len, pre.end());
        vector<int> in_left(in.begin(), in.begin() + left_len);
        vector<int> in_right(in.begin() + left_len + 1, in.end());
        root->left = reBuild(pre_left, in_left);
        root->right = reBuild(pre_right, in_right);
        return root;
    }
    vector<int> solve(vector<int>& pre, vector<int>& in) {
        // write code here
        TreeNode* root = reBuild(pre, in);
        vector<int> res;
        if(!root)
        {
            return res;
        }
        queue<TreeNode*> q;
        q.push(root);
        
        while(!q.empty())
        {
            int len = q.size();
            TreeNode* node;
            for(int i = 0; i < len; i++)
            {
                node = q.front();
                q.pop();
                if(node->left)
                    q.push(node->left);
                if(node->right)
                    q.push(node->right);
            }
            res.push_back(node->val);
        }
        return res;
        
    }
};

发表于 2021-04-20 22:20:00 回复(0)
在模拟还原二叉树的过程中构建右视图,因为dfs是先左子树再右子树的,因此后遍历到的右子树可以覆盖对应层的左边的点,从而形成右视图
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> rightView;
        int len=xianxu.size();
        if(len==0 || len!=zhongxu.size()) {
            return rightView;
        }
        int rootVal=xianxu[0];
        rightView.push_back(rootVal);
        int i;
        for(i=0;i<zhongxu.size();i++) {
            if(zhongxu[i]==rootVal) {
                break;
            }
        }
        int index=1;
        dfs(xianxu,index,zhongxu,0,i-1,rightView,1);
        dfs(xianxu,index,zhongxu,i+1,len-1,rightView,1);
        return rightView;
    }
    void dfs(vector<int>& xianxu, int& index, vector<int>& zhongxu,int left,int right,vector<int>& rightView,int num) {
        if(index==xianxu.size() || left>right) {
            return ;
        }
        if(rightView.size()<=num) {
            rightView.push_back(xianxu[index]); //子树根节点
        } else{
            rightView[num]=xianxu[index];//右边的点覆盖右视图
        }
        int i=0;
        for(i=left;i<=right;i++) {
            if(zhongxu[i]==xianxu[index]) {
                index++;
                dfs(xianxu,index,zhongxu,left,i-1,rightView,num+1);
                dfs(xianxu,index,zhongxu,i+1,right,rightView,num+1);
            }
        }
    }
};


发表于 2021-03-22 17:38:04 回复(0)
class Solution {
private:
    unordered_map<int, int> mp;
public:
    vector<int> solve(vector<int>& xianxu, vector<int>& zhongxu) {
        // write code here
        for(int i=0; i<zhongxu.size(); ++i) {
            mp[zhongxu[i]] = i;
        }
        TreeNode* root = rebuild(xianxu, zhongxu, 0, xianxu.size()-1, 0, zhongxu.size()-1);
        vector<int> res = levelOrder(root);
        return res;
    }
    
    TreeNode* rebuild(vector<int>& preOrder, vector<int>& inOrder, int p1, int p2, int i1, int i2) {
        if(p1>p2) return nullptr;
        TreeNode* node = new TreeNode(preOrder[p1]);
        int r = mp[node->val];
        node->left = rebuild(preOrder, inOrder, p1+1, p1+r-i1, i1, r-1);
        node->right = rebuild(preOrder, inOrder, p1+r-i1+1, p2, r+1, i2);
        return node;
    }
    
    vector<int> levelOrder(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()) {
            int size = q.size();
            for(int i=0; i<size; ++i) {
                TreeNode* node = q.front();
                q.pop();
                if(i==size-1) res.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
        }
        return res;
    }
};
二合一
发表于 2020-12-21 20:58:30 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 求二叉树的右视图
     * @param preOrder int整型一维数组 先序遍历
     * @param inOrder int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    public int[] solve (int[] preOrder, int[] inOrder) {
        // write code here
        List<Integer> result = new ArrayList<>();
        if (preOrder.length < 1 || preOrder.length != inOrder.length) {
            return null;
        }
        // 根据前序遍历和中序遍历构造二叉树
        TreeNode root = buildTree(preOrder, 0, preOrder.length - 1, inOrder, 0, inOrder.length - 1);
        if (root == null) {
            return null;
        }
        // 使用迭代法寻找二叉树的最右侧节点
        Deque<TreeNode> queue = new LinkedList<>();
        queue.addLast(root);
        while (!queue.isEmpty()) {
            // 求出每层节点的数量
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.removeFirst();
                // size - 1即为最右侧节点,加入到result结果列表中
                if (i == size - 1) {
                    result.add(node.val);
                }
                if (node.left != null) {
                    queue.addLast(node.left);
                }
                if (node.right != null) {
                    queue.addLast(node.right);
                }
            }
        }
        return result.stream().mapToInt(x -> x).toArray();
    }

    // 根据前序遍历和中序遍历构造二叉树
    public TreeNode buildTree(int[] preOrder, int preStart, int preEnd, int[] inOrder, int inStart, int inEnd) {
        if (preStart > preEnd || inStart > inEnd) {
            return null;
        }
        int root_val = preOrder[preStart];
        TreeNode root = new TreeNode(root_val);
        int index = 0;
        for (index = 0; index < inOrder.length; index++) {
            if (inOrder[index] == root_val) {
                break;
            }
        }
        int left_length = index - inStart;
        root.left = buildTree(preOrder, preStart + 1, preStart + left_length, inOrder, inStart, index - 1);
        root.right = buildTree(preOrder, preStart + left_length + 1, preEnd, inOrder, index + 1, inEnd);
        return root;
    }
}

编辑于 2024-02-20 02:32:21 回复(0)
class Solution:
    def solve(self , preOrder: List[int], inOrder: List[int]) -> List[int]:
        if not preOrder:
            return []
        res = [preOrder[0]]
        index = inOrder.index(preOrder[0])
        # 左子树的右视图
        left = self.solve(preOrder[1:index+1], inOrder[:index])
        # 右子树的右视图
        right = self.solve(preOrder[index+1:], inOrder[index+1:])
        # 优先取右子树,剩余取左子树
        return res + right + left[len(right):]
编辑于 2024-01-06 01:46:22 回复(1)
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 求二叉树的右视图
     * @param preOrder int整型一维数组 先序遍历
     * @param inOrder int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    public int[] solve (int[] preOrder, int[] inOrder) {
        // write code here
        TreeNode root = rebuildTree(preOrder, inOrder);
        if (root == null) {
            return null;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        List<Integer> res = new ArrayList<>();
        while (!queue.isEmpty()) {
            int currentSize = queue.size();
            for (int i = 0; i < currentSize; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.add(node.left);
                }
                if (node.right != null) {
                    queue.add(node.right);
                }
                if (i == currentSize - 1) {
                    res.add(node.val);
                }
            }
        }
        return res.stream().mapToInt(Integer::intValue).toArray();
    }

    public TreeNode rebuildTree(int[] preOrder, int[] inOrder) {
        int n = preOrder.length;
        int m = preOrder.length;
        if (n == 0 || m == 0) {
            return null;
        }
        TreeNode root = new TreeNode(preOrder[0]);
        for (int i = 0; i < n; i++) {
            if (preOrder[0] == inOrder[i]) {
                root.left = rebuildTree(Arrays.copyOfRange(preOrder, 1, i + 1), Arrays.copyOfRange(inOrder, 0, i + 1));
                root.right = rebuildTree(Arrays.copyOfRange(preOrder, i + 1, n), Arrays.copyOfRange(inOrder, i + 1, m));
            }
        }
        return root;
    }
}
发表于 2023-10-09 14:00:18 回复(0)