华为OD机试真题 新系统 2026-05-31 Python&JS 实现【链表数字游戏】
目录
题目
初始队列的顺序(从队首到队尾)处理每个人,每人仅处理一次,处理规则如下:
在一个数字游戏中,m(1≤m≤10^5)个参与者排成一队,每人持有一个整数号码牌n (0≤n≤10^3)。游戏只进行一轮,按照
1.如果号码是3的倍数,则将其淘汰(从队列中移除)。
2.否则,如果号码的十进制表示中包含数字3,则将其移动到队尾。
3.否则,如果号码的十进制表示中包含数字2,则将其移动到队首。
4.否则,位置保持不变。
5.对于规则2、3:不论插入队首还是队尾,他们的相对顺序与他们在初始队列中的相对顺序保持一致。
优先级说明:
·如果一个数字同时满足规则1和规则2,或同时满足规则1和规则3,则遵从规则1(淘汰)。
·如果一个数字同时满足规则2和规则3(即同时包含数字2和3,且不是3的倍数),则遵从规则2(移动到队尾)
输入描述
给定一个表示所有排成队列的链表的头ListNode
输出描述
1.输出一行整数,表示最终队列的号码牌顺序,用空格分隔2.超过号码牌整数范围或者人数超过总人数限制,返回“-1”
样例1
输入
12 23 7 13 8
输出
7 8 23 13
说明处理过程:
1.淘汰12->[23,7,13,8]
2.23移动到队尾->[7,13,8,23]
3.7不变->[7,13,8,23]
4.13移动到队尾->[7,8,23,13]
5.8不变->[7,8,23,13]
最终顺序为7 8 23 13。
样例2输入
6 23 32 33 2 3
输出
2 23 32
说明1.6:是3的倍数,淘汰。
2.23:同时包含2和3,但包含数字3所以触发规则2(优先级高于规则3),移动到队尾。
3.32:同时包含2和3,但包含数字3所以触发规则2(优先级高于规则3),移动到队尾。
4.33:是3的倍数(33%3==0),淘汰。
5.2:包含数字2,移动到队首。
6.3:是3的倍数,淘汰。
思路
三列表收集 + 顺序拼接(O(m))
预处理:
- 将输入按空格分割为字符串数组,再转整数列表。
- 人数 m 或号码 n 超出范围则直接输出 "-1" 并返回。
状态定义:
- head:需要移动到队首的元素列表(按初始顺序收集)。
- middle:保持不动的元素列表。
- tail:需要移动到队尾的元素列表。
核心逻辑:
1. 遍历每个号码 n:
a) if n % 3 == 0 → 跳过(淘汰)。
b) else if 数字 '3' in str(n) → tail.append(n)。
c) else if 数字 '2' in str(n) → head.append(n)。
d) else → middle.append(n)。
2. 最终输出 head + middle + tail(空格分隔)。
复杂度:
- 时间 O(m):每个元素 O(1) 整除和字符串包含判断。
- 空间 O(m):三个列表存储最多 m 个元素。
Code
import sys
# 总人数上限
MAX_M = 10 ** 5
# 号码牌范围
MAX_N = 10 ** 3
def solve(arr):
"""
按规则处理数字队列,返回最终顺序列表。
算法思路(三列表收集,O(m) 时间,O(m) 空间):
---------------------------------------------------------------
题目要求按初始顺序依次处理每人一次,且被移动到队首/队尾的元素
保持初始相对顺序。因此无需模拟队列的增删操作,只需用三个列表
分别收集"去队首""不动""去队尾"的元素,最后拼接即可:
- head:需要移动到队首的元素(按初始顺序追加,自然保持相对顺序)
- middle:不动元素(按初始顺序追加)
- tail:需要移动到队尾的元素(按初始顺序追加)
最终队列 = head + middle + tail
---------------------------------------------------------------
"""
head = [] # 规则 3:移动到队首的元素
middle = [] # 规则 4:不动的元素
tail = [] # 规则 2:移动到队尾的元素
for num in arr:
# 规则 1:3 的倍数 → 淘汰
if num % 3 == 0:
continue
# 规则 2:包含数字 3 → 队尾(优先级高于规则 3)
if '3' in str(num):
tail.append(num)
# 规则 3:包含数字 2 → 队首
elif '2' in str(num):
head.append(num)
# 规则 4:其他情况 → 不动
else:
middle.append(num)
# head + middle + tail 即为最终顺序
return head + middle + tail
def main():
"""
从标准输入读取一行空格分隔的整数,输出处理后的队列。
若人数或号码牌范围超出限制,输出 "-1"。
"""
try:
line = sys.stdin.readline().strip()
if not line:
return
parts = line.split()
m = len(parts)
# 校验人数是否超限
if m > MAX_M:
print(-1)
return
# 校验号码牌范围
arr = []
for p in parts:
try:
num = int(p)
except ValueError:
print(-1)
return
if num < 0 or num > MAX_N:
print(-1)
return
arr.append(num)
result = solve(arr)
# 输出结果,空格分隔;若结果为空则输出空行
if result:
print(' '.join(map(str, result)))
else:
print()
except Exception:
# 任何异常输出 -1 作为安全兜底
print(-1)
if __name__ == '__main__':
main()
JS
const readline = require('readline');
const MAX_M = 100000;
const MAX_N = 1000;
/**
* 按规则处理数字队列,返回最终顺序数组。
*
* 算法思路(三列表收集,O(m) 时间,O(m) 空间):
* ---------------------------------------------------------------
* 题目要求按初始顺序依次处理每人一次,且被移动到队首/队尾的元素
* 保持初始相对顺序。因此用三个数组分别收集,最后拼接即可。
*
* @param {number[]} arr 初始队列的号码牌数组
* @returns {number[]} 处理后的最终顺序
*/
function solve(arr) {
const head = []; // 规则 3:移动到队首的元素
const middle = []; // 规则 4:不动的元素
const tail = []; // 规则 2:移动到队尾的元素
for (const num of arr) {
// 规则 1:3 的倍数 → 淘汰
if (num % 3 === 0) {
continue;
}
// 规则 2:包含数字 3 → 队尾(优先级高于规则 3)
if (String(num).includes('3')) {
tail.push(num);
}
// 规则 3:包含数字 2 → 队首
else if (String(num).includes('2')) {
head.push(num);
}
// 规则 4:其他情况 → 不动
else {
middle.push(num);
}
}
// head + middle + tail 即为最终顺序
return head.concat(middle, tail);
}
// ---- 主程序 ----
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
const inputLines = [];
rl.on('line', (line) => {
inputLines.push(line);
});
rl.on('close', () => {
try {
const line = inputLines.join('').trim();
if (!line) {
console.log('');
return;
}
const parts = line.split(/\s+/);
const m = parts.length;
// 校验人数是否超限
if (m > MAX_M) {
console.log(-1);
return;
}
// 校验号码牌范围
const arr = [];
for (const p of parts) {
const num = parseInt(p, 10);
if (isNaN(num) || num < 0 || num > MAX_N) {
console.log(-1);
return;
}
arr.push(num);
}
const result = solve(arr);
if (result.length > 0) {
console.log(result.join(' '));
} else {
console.log('');
}
} catch (e) {
console.log(-1);
}
});
【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java&Go】:Java&Go真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为od机试面试交流群】【文章底部有二维码链接,可扫码加交流群】
华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。
更多推荐





所有评论(0)