华为笔试 华为秋招 华为笔试题 0928
笔试时间:2025年9月28日
往年笔试合集:
第一题:组织架构管理系统
你正在开发一个企业的组织架构管理系统,公司的组织架构被简化表示为一棵二叉树。树的每个节点代表一个员工,树的层级越低则级别越高,高级别作为主管,管辖其子树涉及的所有员工。
每个人有一个唯一的工号,工号以整数值表示,范围是[0, 10^9]。
此管理系统需要提供一个统计能力,对任意两名员工,找到他们级别最低的共同主管,返回当前主管管辖的人员个数。
注意:
- 如果两名员工本身存在上下级关系,共同主管为级别较高的员工。
- 员工总数 ≤ 10000。
- 待检索员工的工号一定在给定的二叉树中,且两位员工工号不同。
输入描述
第一行为一个整数,表示输入的节点个数。 第二行为一行数字,由空格分割,每个数字表示一颗满二叉树各层从左到右的节点。值为员工工号,-1代表该节点不存在。 第三行为两个数字,用空格分割,表示待检索的两名员工工号。
输出描述
输出级别最低的共同主管管辖的人员总个数(不包括自身)。
样例输入
12
2 3 5 1 7 6 8 -1 -1 0 4 -1
0 3
样例输出
4
参考题解
解题思路:
- 这是一个寻找最近公共祖先(LCA)的问题
- 先构建二叉树,然后找到两个节点的最近公共祖先
- 计算以该祖先为根的子树大小
- 子树大小减1就是管辖人员总数
C++:
#include <iostream> #include <vector> #include <queue> #include <sstream> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; TreeNode* buildTree(vector<string>& nodes) { if (nodes.empty() || nodes[0] == "-1") return nullptr; TreeNode* root = new TreeNode(stoi(nodes[0])); queue<TreeNode*> q; q.push(root); int i = 1; while (!q.empty() && i < nodes.size()) { TreeNode* current = q.front(); q.pop(); if (i < nodes.size() && nodes[i] != "-1") { current->left = new TreeNode(stoi(nodes[i])); q.push(current->left); } i++; if (i < nodes.size() && nodes[i] != "-1") { current->right = new TreeNode(stoi(nodes[i])); q.push(current->right); } i++; } return root; } TreeNode* findLCA(TreeNode* root, int p, int q) { if (!root || root->val == p || root->val == q) { return root; } TreeNode* left = findLCA(root->left, p, q); TreeNode* right = findLCA(root->right, p, q); if (left && right) return root; return left ? left : right; } int countNodes(TreeNode* root) { if (!root) return 0; return 1 + countNodes(root->left) + countNodes(root->right); } int main() { int n; cin >> n; cin.ignore(); string line; getline(cin, line); istringstream iss(line); vector<string> nodes; string node; while (iss >> node) { nodes.push_back(node); } int emp1, emp2; cin >> emp1 >> emp2; TreeNode* root = buildTree(nodes); TreeNode* lca = findLCA(root, emp1, emp2); int total = countNodes(lca); cout << total - 1 << endl; return 0; }
Java:
import java.util.*; class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Solution { public static TreeNode buildTree(String[] nodes) { if (nodes.length == 0 || nodes[0].equals("-1")) return null; TreeNode root = new TreeNode(Integer.parseInt(nodes[0])); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int i = 1; while (!queue.isEmpty() && i < nodes.length) { TreeNode current = queue.poll(); if (i < nodes.length && !nodes[i].equals("-1")) { current.left = new TreeNode(Integer.parseInt(nodes[i])); queue.offer(current.left); } i++; if (i < nodes.length && !nodes[i].equals("-1")) { current.right = new TreeNode(Integer.parseInt(nodes[i])); queue.offer(current.right); } i++; } return root; } public static TreeNode findLCA(TreeNode root, int p, int q) { if (root == null || root.val == p || root.val == q) { return root; } TreeNode left = findLCA(root.left, p, q); TreeNode right = findLCA(root.right, p, q); if (left != null && right != null) return root; return left != null ? left : right; } public static int countNodes(TreeNode root) { if (root == null) return 0; return 1 + countNodes(root.left) + countNodes(root.right); } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.nextLine(); String[] nodes = scanner.nextLine().split(" "); int emp1 = scanner.nextInt(); int emp2 = scanner.nextInt(); TreeNode root = buildTree(nodes); TreeNode lca = findLCA(root, emp1, emp2); int total = countNodes(lca); System.out.println(total - 1); } }
Python:
import sys from collections import deque class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildtree(nodes_str: list[str]) -> TreeNode: if not nodes_str or nodes_str[0] == '-1': return None vals = [int(n) if n != '-1' else None for n in nodes_str] root = TreeNode(vals[0]) q = deque([root]) i = 1 while q and i < len(vals): current_node = q.popleft() # 处理左子节点 if i < len(vals) and vals[i] is not None: left_child = TreeNode(vals[i]) current_node.left = left_child q.append(left_child) i += 1 # 处理右子节点 if i < len(vals) and vals[i] is not None: right_child = TreeNode(vals[i]) current_node.right = right_child q.append(right_child) i += 1 return root def findlca(root: TreeNode, p_val: int, q_val: int) -> TreeNode: if not root or root.val == p_val or root.val == q_val: return root left_lca = findlca(root.left, p_val, q_val) right_lca = findlca(root.right, p_val, q_val) # 如果p和q分别在左右子树,则当前root是LCA if left_lca and right_lca: return root # 否则,LCA在已经找到p或q的那个子树中 return left_lca if left_lca else right_lca def countnode(node: TreeNode) -> int: if not node: return 0 return 1 + countnode(node.left) + countnode(node.right) n = int(sys.stdin.readline()) nodes_input = sys.stdin.readline().strip().split() emp1, emp2 = map(int, sys.stdin.readline().strip().split()) root = buildtree(nodes_input) lca_node = findlca(root, emp1, emp2) total_in_subtree = countnode(lca_node) subordinates_count = total_in_subtree - 1 print(subordinates_count)
第二题:奖项设置
部门准备了一批奖品用于举办抽奖活动,奖品的价值为给定的正整数数组values,其中values[i]表示第i个奖品的价值。每位获奖者可以选择不限个数最大价值limit的奖品组合,获奖者选择奖品的策略为在limit限制内优先选择单价最高的奖品,请计算最少可以设置多少个奖项。
输入描述
第一行:正整数len,表述奖品价值数组values的长度,1 ≤ len ≤ 10^3; 第二行:正整数数组values,长度为len,其中values[i]表示第i个奖品的价值,1 ≤ values[i] ≤ 10^4; 第三行:正整数limit,表示每个获奖者可以获得的最大奖品价值,1 ≤ limit ≤ 10^4。
输出描述
输出一个整数,代表本次抽奖活动可以设置最少的奖项数量。
样例输入
2
1 2
3
样例输出
1
参考题解
解题思路:
类似"船载人"问题的贪心算法:
- 奖品按价值从小到大排序
- 使用双指针,尝试将最贵的奖品(右指针)和最便宜的奖品(左指针)配对
- 如果能放进同一个奖项,就一起放,否则最贵的单独开一个奖项
- 循环直到所有奖品都被分配完
C++:
#include <iostream> #include <vector> #include <algorithm> using namespace std; int solve() { int n; cin >> n; vector<int> values(n); for (int i = 0; i < n; i++) { cin >> values[i]; } in
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南