最近在准备OPPO的结构工程师岗位笔试,发现他们的算法题设计很有层次感。今天我就以2026年3月14日的这套真题为例,详细拆解每道题的解题思路和实现细节,希望能给同样在准备笔试的同学一些启发。
这套题共3道,难度梯度明显:第一题是基础的模拟题,考察对题意理解和基础编码能力;第二题披着斐波那契的外衣,实则考察数学公式推导能力;第三题则需要通过问题分析找到状态压缩的关键。下面我会逐题分析,不仅给出解法,还会分享我在解题过程中踩过的坑和优化思路。
第一题的要求是:给定一个数组,找出所有下标是3的倍数的元素,判断它们的和是否能被3整除。这属于典型的模拟题,考察的是对题目要求的准确理解和基础编码能力。
关键点在于:
python复制def check_divisible_by_3(arr):
total = 0
for i in range(len(arr)):
if (i + 1) % 3 == 0: # 假设题目说明下标从1开始
total += arr[i]
return total % 3 == 0
注意事项:
时间复杂度:O(n),必须遍历整个数组
空间复杂度:O(1),只用了常数额外空间
虽然这道题很简单,但在实际笔试中,这种基础题一定要确保100%正确率,因为后面的题目会越来越难。
第二题表面上是关于斐波那契数列的题目,但实际考察的是如何将带权区间和转化为前缀和公式。题目给出一个数组,要求计算多个查询区间[l,r]内,每个元素乘以其位置对应的斐波那契数后的和。
直接暴力计算每个查询的时间复杂度是O(n*q),当n和q都很大时会超时。正确的做法是先推导出前缀和公式:
设S[i] = F[1]*a[1] + F[2]*a[2] + ... + F[i]*a[i]
那么区间[l,r]的和就是S[r] - S[l-1]
python复制def preprocess(arr):
n = len(arr)
fib = [0] * (n + 2)
fib[1] = 1
fib[2] = 1
for i in range(3, n + 1):
fib[i] = fib[i-1] + fib[i-2]
prefix = [0] * (n + 1)
for i in range(1, n + 1):
prefix[i] = prefix[i-1] + fib[i] * arr[i-1]
return prefix
def query(prefix, l, r):
return prefix[r] - prefix[l-1]
关键点:
预处理:
总复杂度:O(n + q),可以高效处理大规模查询。
第三题看起来数据范围很大,但实际有效状态只与数字1∼9有关。题目要求从数字1∼n中选择一个子集,然后排列这些数字组成新的数,求满足特定条件的数的个数。
关键观察:
python复制from itertools import combinations
from math import factorial
from collections import Counter
def count_numbers(n, k):
count = 0
for size in range(1, min(n, 9) + 1):
for digits in combinations('123456789', size):
# 计算所有排列
perms = factorial(size)
# 如果有重复数字需要去重
cnt = Counter(digits)
for v in cnt.values():
perms //= factorial(v)
# 检查是否满足题目条件
if some_condition(digits):
count += perms
return count
优化技巧:
最坏复杂度是O(2^9 * 9!),但实际上通过剪枝可以大大减少计算量:
在OPPO的笔试中,我建议的时间分配是:
一定要留出5-10分钟检查边界条件和提交代码。
针对OPPO的结构工程师笔试,建议重点准备:
在准备过程中,我发现OPPO的题目虽然有一定难度,但很少有偏题怪题,都是考察扎实的算法基础和问题分析能力。建议在平时练习时,不仅要写出正确解法,还要思考是否有优化空间,以及如何向面试官清晰表达自己的思路。