华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
有一棵二叉树,每个节点由一个大写字母标识(最多26个节点)。
现有两组字母,分别表示后序遍历(左孩子->右孩子->父节点)和中序遍历(左孩子->父节点->右孩子)的结果,请输出层次遍历的结果。
二、输入描述
输入为两个字符串,分别是二叉树的后续遍历和中序遍历结果。
三、输出描述
输出二叉树的层次遍历结果。
四、测试用例
1、输入
CBEFDA CBAEDF
2、输出
ABDCEF
3、说明
二叉树为:
A
/
B D
/ /
C E F
五、解题思路
为了从后序遍历和中序遍历结果构建二叉树,然后输出层次遍历结果,我们可以按照以下步骤进行:
- 从后序遍历和中序遍历构建二叉树:
- 后序遍历的最后一个节点是根节点。
- 在中序遍历中找到该根节点,根节点左边的部分是左子树,右边的部分是右子树。
- 递归地对左右子树重复上述过程,直到构建完整的二叉树。
- 进行层次遍历:
- 使用队列进行层次遍历,从根节点开始,将每一层的节点加入队列,并依次输出。
六、Python算法源码
from collections import dequeclass TreeNode:def __init__(self, val):self.val = valself.left = Noneself.right = Nonedef build_tree(post_order, in_order):if not post_order or not in_order:return Nonereturn build_tree_helper(post_order, 0, len(post_order) - 1, in_order, 0, len(in_order) - 1)def build_tree_helper(post_order, post_start, post_end, in_order, in_start, in_end):if post_start > post_end or in_start > in_end:return None# 后序遍历的最后一个节点是根节点root_val = post_order[post_end]root = TreeNode(root_val)# 在中序遍历中找到根节点的位置root_index = in_order.index(root_val)# 计算左子树的大小left_tree_size = root_index - in_start# 构建左子树root.left = build_tree_helper(post_order, post_start, post_start + left_tree_size - 1, in_order, in_start, root_index - 1)# 构建右子树root.right = build_tree_helper(post_order, post_start + left_tree_size, post_end - 1, in_order, root_index + 1, in_end)return rootdef level_order_traversal(root):if root is None:return ""result = []queue = deque([root])while queue:current = queue.popleft()result.append(current.val)if current.left is not None:queue.append(current.left)if current.right is not None:queue.append(current.right)return ''.join(result)def main():# 读取输入的后序遍历和中序遍历字符串post_order = input("Enter post-order traversal: ")in_order = input("Enter in-order traversal: ")# 构建二叉树root = build_tree(post_order, in_order)# 输出层次遍历结果level_order_result = level_order_traversal(root)print(level_order_result)if __name__ == "__main__":main()
七、JavaScript算法源码
class TreeNode {constructor(val) {this.val = val;this.left = null;this.right = null;}
}function buildTree(postOrder, inOrder) {if (!postOrder || !inOrder || postOrder.length === 0 || inOrder.length === 0) {return null;}return buildTreeHelper(postOrder, 0, postOrder.length - 1, inOrder, 0, inOrder.length - 1);
}function buildTreeHelper(postOrder, postStart, postEnd, inOrder, inStart, inEnd) {if (postStart > postEnd || inStart > inEnd) {return null;}// 后序遍历的最后一个节点是根节点const rootVal = postOrder[postEnd];const root = new TreeNode(rootVal);// 在中序遍历中找到根节点的位置const rootIndex = inOrder.indexOf(rootVal);// 计算左子树的大小const leftTreeSize = rootIndex - inStart;// 构建左子树root.left = buildTreeHelper(postOrder, postStart, postStart + leftTreeSize - 1, inOrder, inStart, rootIndex - 1);// 构建右子树root.right = buildTreeHelper(postOrder, postStart + leftTreeSize, postEnd - 1, inOrder, rootIndex + 1, inEnd);return root;
}function levelOrderTraversal(root) {if (!root) {return "";}let result = "";const queue = [];queue.push(root);while (queue.length > 0) {const current = queue.shift();result += current.val;if (current.left !== null) {queue.push(current.left);}if (current.right !== null) {queue.push(current.right);}}return result;
}function main() {// 读取输入的后序遍历和中序遍历字符串const postOrder = prompt("Enter post-order traversal:");const inOrder = prompt("Enter in-order traversal:");// 构建二叉树const root = buildTree(postOrder, inOrder);// 输出层次遍历结果const levelOrderResult = levelOrderTraversal(root);console.log(levelOrderResult);
}// 调用 main 函数
main();
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义二叉树节点结构体
typedef struct TreeNode {char val;struct TreeNode* left;struct TreeNode* right;
} TreeNode;// 创建新节点
TreeNode* createNode(char val) {TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));newNode->val = val;newNode->left = NULL;newNode->right = NULL;return newNode;
}// 根据后序遍历和中序遍历构建二叉树
TreeNode* buildTreeHelper(char* postOrder, int postStart, int postEnd, char* inOrder, int inStart, int inEnd) {if (postStart > postEnd || inStart > inEnd) {return NULL;}// 后序遍历的最后一个节点是根节点char rootVal = postOrder[postEnd];TreeNode* root = createNode(rootVal);// 在中序遍历中找到根节点的位置int rootIndex;for (rootIndex = inStart; rootIndex <= inEnd; rootIndex++) {if (inOrder[rootIndex] == rootVal) {break;}}// 计算左子树的大小int leftTreeSize = rootIndex - inStart;// 构建左子树root->left = buildTreeHelper(postOrder, postStart, postStart + leftTreeSize - 1, inOrder, inStart, rootIndex - 1);// 构建右子树root->right = buildTreeHelper(postOrder, postStart + leftTreeSize, postEnd - 1, inOrder, rootIndex + 1, inEnd);return root;
}// 根据后序遍历和中序遍历字符串构建二叉树
TreeNode* buildTree(char* postOrder, char* inOrder) {int len = strlen(postOrder);if (len == 0) {return NULL;}return buildTreeHelper(postOrder, 0, len - 1, inOrder, 0, len - 1);
}// 层次遍历二叉树并输出结果
void levelOrderTraversal(TreeNode* root) {if (root == NULL) {return;}TreeNode** queue = (TreeNode**)malloc(100 * sizeof(TreeNode*));int front = 0;int rear = 0;queue[rear++] = root;while (front < rear) {TreeNode* current = queue[front++];printf("%c", current->val);if (current->left != NULL) {queue[rear++] = current->left;}if (current->right != NULL) {queue[rear++] = current->right;}}free(queue);
}// 释放二叉树节点的内存
void freeTree(TreeNode* root) {if (root != NULL) {freeTree(root->left);freeTree(root->right);free(root);}
}int main() {char postOrder[100];char inOrder[100];// 读取输入的后序遍历和中序遍历字符串printf("Enter post-order traversal: ");scanf("%s", postOrder);printf("Enter in-order traversal: ");scanf("%s", inOrder);// 构建二叉树TreeNode* root = buildTree(postOrder, inOrder);// 输出层次遍历结果levelOrderTraversal(root);printf("\n");// 释放二叉树的内存freeTree(root);return 0;
}
九、C++算法源码
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>using namespace std;// 定义二叉树节点结构体
struct TreeNode {char val;TreeNode* left;TreeNode* right;TreeNode(char x) : val(x), left(nullptr), right(nullptr) {}
};// 根据后序遍历和中序遍历构建二叉树
TreeNode* buildTreeHelper(const string& postOrder, int postStart, int postEnd, const string& inOrder, int inStart, int inEnd, unordered_map<char, int>& inOrderMap) {if (postStart > postEnd || inStart > inEnd) {return nullptr;}// 后序遍历的最后一个节点是根节点char rootVal = postOrder[postEnd];TreeNode* root = new TreeNode(rootVal);// 在中序遍历中找到根节点的位置int rootIndex = inOrderMap[rootVal];// 计算左子树的大小int leftTreeSize = rootIndex - inStart;// 构建左子树root->left = buildTreeHelper(postOrder, postStart, postStart + leftTreeSize - 1, inOrder, inStart, rootIndex - 1, inOrderMap);// 构建右子树root->right = buildTreeHelper(postOrder, postStart + leftTreeSize, postEnd - 1, inOrder, rootIndex + 1, inEnd, inOrderMap);return root;
}// 根据后序遍历和中序遍历字符串构建二叉树
TreeNode* buildTree(const string& postOrder, const string& inOrder) {unordered_map<char, int> inOrderMap;for (int i = 0; i < inOrder.size(); ++i) {inOrderMap[inOrder[i]] = i;}return buildTreeHelper(postOrder, 0, postOrder.size() - 1, inOrder, 0, inOrder.size() - 1, inOrderMap);
}// 层次遍历二叉树并输出结果
void levelOrderTraversal(TreeNode* root) {if (root == nullptr) {return;}queue<TreeNode*> q;q.push(root);while (!q.empty()) {TreeNode* current = q.front();q.pop();cout << current->val;if (current->left != nullptr) {q.push(current->left);}if (current->right != nullptr) {q.push(current->right);}}
}// 释放二叉树节点的内存
void freeTree(TreeNode* root) {if (root != nullptr) {freeTree(root->left);freeTree(root->right);delete root;}
}int main() {string postOrder;string inOrder;// 读取输入的后序遍历和中序遍历字符串cout << "Enter post-order traversal: ";cin >> postOrder;cout << "Enter in-order traversal: ";cin >> inOrder;// 构建二叉树TreeNode* root = buildTree(postOrder, inOrder);// 输出层次遍历结果levelOrderTraversal(root);cout << endl;// 释放二叉树的内存freeTree(root);return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。