华为笔试 华为秋招 华为笔试题 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等多种语言做法集合指南

