解题思路

这是一道二叉树重建和遍历的综合题目,主要思路如下:

  1. 问题分析:

    • 给定二叉树的层序遍历和中序遍历
    • 需要重建二叉树
    • 输出叶子节点、先序遍历和后序遍历
    • 树的深度不超过10,节点数小于1024
  2. 解决方案:

    • 根据层序和中序遍历重建二叉树
    • 使用递归方法构建树结构
    • 分别实现三种遍历方法
    • 特别处理叶子节点的识别
  3. 实现细节:

    • 使用哈希表存储中序遍历的节点位置
    • 递归构建左右子树
    • 按要求格式化输出结果

代码

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left, *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
private:
    unordered_map<int, int> pos;
    vector<int> leaves;
    vector<int> preorder, postorder;
    
public:
    TreeNode* buildTree(vector<int>& level, vector<int>& inorder) {
        // 建立中序遍历的值到位置的映射
        for(int i = 0; i < inorder.size(); i++) {
            pos[inorder[i]] = i;
        }
        return construct(level, inorder, 0, inorder.size()-1);
    }
    
    TreeNode* construct(vector<int>& level, vector<int>& inorder, int left, int right) {
        if(left > right) return NULL;
        
        // 在level中找到第一个在当前中序范围内的值作为根节点
        TreeNode* root = NULL;
        for(int i = 0; i < level.size(); i++) {
            int pos_in_inorder = pos[level[i]];
            if(pos_in_inorder >= left && pos_in_inorder <= right) {
                root = new TreeNode(level[i]);
                root->left = construct(level, inorder, left, pos_in_inorder-1);
                root->right = construct(level, inorder, pos_in_inorder+1, right);
                break;
            }
        }
        return root;
    }
    
    void getLeaves(TreeNode* root) {
        if(!root) return;
        if(!root->left && !root->right) {
            leaves.push_back(root->val);
            return;
        }
        getLeaves(root->left);
        getLeaves(root->right);
    }
    
    void preOrder(TreeNode* root) {
        if(!root) return;
        preorder.push_back(root->val);
        preOrder(root->left);
        preOrder(root->right);
    }
    
    void postOrder(TreeNode* root) {
        if(!root) return;
        postOrder(root->left);
        postOrder(root->right);
        postorder.push_back(root->val);
    }
    
    void printResult(TreeNode* root) {
        // 获取所有结果
        getLeaves(root);
        preOrder(root);
        postOrder(root);
        
        // 按格式输出
        for(int i = 0; i < leaves.size(); i++) {
            cout << leaves[i] << (i == leaves.size()-1 ? "\n" : " ");
        }
        for(int i = 0; i < preorder.size(); i++) {
            cout << preorder[i] << (i == preorder.size()-1 ? "\n" : " ");
        }
        for(int i = 0; i < postorder.size(); i++) {
            cout << postorder[i] << (i == postorder.size()-1 ? "\n" : " ");
        }
    }
};

int main() {
    int n;
    vector<int> level, inorder;
    
    // 读入层序遍历
    string num;
    while(cin >> num && num != "\n") {
        level.push_back(stoi(num));
    }
    
    // 读入中序遍历
    while(cin >> num && num != "\n") {
        inorder.push_back(stoi(num));
    }
    
    Solution solution;
    TreeNode* root = solution.buildTree(level, inorder);
    solution.printResult(root);
    
    return 0;
}
import java.util.*;

class TreeNode {
    int val;
    TreeNode left, right;
    TreeNode(int x) { val = x; }
}

public class Main {
    private Map<Integer, Integer> pos = new HashMap<>();
    private List<Integer> leaves = new ArrayList<>();
    private List<Integer> preorder = new ArrayList<>();
    private List<Integer> postorder = new ArrayList<>();
    
    public TreeNode buildTree(int[] level, int[] inorder) {
        // 建立中序遍历的值到位置的映射
        for(int i = 0; i < inorder.length; i++) {
            pos.put(inorder[i], i);
        }
        return construct(level, inorder, 0, inorder.length-1);
    }
    
    private TreeNode construct(int[] level, int[] inorder, int left, int right) {
        if(left > right) return null;
        
        // 在level中找到第一个在当前中序范围内的值作为根节点
        TreeNode root = null;
        for(int i = 0; i < level.length; i++) {
            int posInInorder = pos.get(level[i]);
            if(posInInorder >= left && posInInorder <= right) {
                root = new TreeNode(level[i]);
                root.left = construct(level, inorder, left, posInInorder-1);
                root.right = construct(level, inorder, posInInorder+1, right);
                break;
            }
        }
        return root;
    }
    
    private void getLeaves(TreeNode root) {
        if(root == null) return;
        if(root.left == null && root.right == null) {
            leaves.add(root.val);
            return;
        }
        getLeaves(root.left);
        getLeaves(root.right);
    }
    
    private void preOrder(TreeNode root) {
        if(root == null) return;
        preorder.add(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }
    
    private void postOrder(TreeNode root) {
        if(root == null) return;
        postOrder(root.left);
        postOrder(root.right);
        postorder.add(root.val);
    }
    
    private void printResult(TreeNode root) {
        // 获取所有结果
        getLeaves(root);
        preOrder(root);
        postOrder(root);
        
        // 按格式输出叶子节点
        for(int i = 0; i < leaves.size(); i++) {
            System.out.print(leaves.get(i));
            if(i < leaves.size() - 1) System.out.print(" ");
        }
        System.out.println();
        
        // 输出先序遍历
        for(int i = 0; i < preorder.size(); i++) {
            System.out.print(preorder.get(i));
            if(i < preorder.size() - 1) System.out.print(" ");
        }
        System.out.println();
        
        // 输出后序遍历
        for(int i = 0; i < postorder.size(); i++) {
            System.out.print(postorder.get(i));
            if(i < postorder.size() - 1) System.out.print(" ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 读入层序遍历
        String[] levelStr = sc.nextLine().split(" ");
        int[] level = new int[levelStr.length];
        for(int i = 0; i < levelStr.length; i++) {
            level[i] = Integer.parseInt(levelStr[i]);
        }
        
        // 读入中序遍历
        String[] inorderStr = sc.nextLine().split(" ");
        int[] inorder = new int[inorderStr.length];
        for(int i = 0; i < inorderStr.length; i++) {
            inorder[i] = Integer.parseInt(inorderStr[i]);
        }
        
        Main solution = new Main();
        TreeNode root = solution.buildTree(level, inorder);
        solution.printResult(root);
        
        sc.close();
    }
}
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def __init__(self):
        self.pos = {}
        self.leaves = []
        self.preorder = []
        self.postorder = []
    
    def buildTree(self, level, inorder):
        # 建立中序遍历的值到位置的映射
        for i, val in enumerate(inorder):
            self.pos[val] = i
        return self.construct(level, inorder, 0, len(inorder)-1)
    
    def construct(self, level, inorder, left, right):
        if left > right:
            return None
        
        # 在level中找到第一个在当前中序范围内的值作为根节点
        root = None
        for val in level:
            pos_in_inorder = self.pos[val]
            if left <= pos_in_inorder <= right:
                root = TreeNode(val)
                root.left = self.construct(level, inorder, left, pos_in_inorder-1)
                root.right = self.construct(level, inorder, pos_in_inorder+1, right)
                break
        return root
    
    def getLeaves(self, root):
        if not root:
            return
        if not root.left and not root.right:
            self.leaves.append(root.val)
            return
        self.getLeaves(root.left)
        self.getLeaves(root.right)
    
    def preOrder(self, root):
        if not root:
            return
        self.preorder.append(root.val)
        self.preOrder(root.left)
        self.preOrder(root.right)
    
    def postOrder(self, root):
        if not root:
            return
        self.postOrder(root.left)
        self.postOrder(root.right)
        self.postorder.append(root.val)
    
    def printResult(self, root):
        # 获取所有结果
        self.getLeaves(root)
        self.preOrder(root)
        self.postOrder(root)
        
        # 按格式输出
        print(" ".join(map(str, self.leaves)))
        print(" ".join(map(str, self.preorder)))
        print(" ".join(map(str, self.postorder)))

def main():
    # 读入层序遍历
    level = list(map(int, input().split()))
    # 读入中序遍历
    inorder = list(map(int, input().split()))
    
    solution = Solution()
    root = solution.buildTree(level, inorder)
    solution.printResult(root)

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:树的重建和遍历
  • 时间复杂度: - 重建树需要在层序遍历中查找
  • 空间复杂度: - 存储树结构和遍历结果