在科技行业竞争越来越激烈的当下, IBM OA 依然保持着一贯风格:题目不偏,但对基础能力要求极高。我们把近几年 IBM 高频出现的 6 类算法题系统梳理一遍。把每一题背后的思维路径讲清楚,让你在考场上能做到:看到题型 → 快速定位解法 → 稳定写出代码。

题目 1:最多不重叠时间区间
描述:给定两个长度为 n 的数组 startTime 和 endTime,每个区间为左闭右开 [startTime[i], endTime[i])。求最多能选择多少个互不重叠的区间。
样例:
- n=3, start=[1,1,2], end=[3,2,4] → 输出 2(选 [1,2) 和 [2,4))
约束:n ≤ 10⁵,时间 1~10⁹
思路:经典活动选择问题。按结束时间排序,贪心选择当前最早结束且不与已选冲突的区间。
代码(Python):
def maxNonOverlapping(start, end):
intervals = sorted(zip(start, end), key=lambda x: x[1])
count = 0
last_end = -float('inf')
for s, e in intervals:
if s >= last_end:
count += 1
last_end = e
return count
时间复杂度:O(n log n)
题目 2:股票最大涨幅差(单次买卖最大利润变种)
描述:给定整数数组,找到 i < j 且 arr[i] < arr[j] 时,arr[j] – arr[i] 的最大值。若不存在,返回 -1。
样例:
- [5,3,6,7,4] → 4(7-3)
- [4,3,2,1] → -1
约束:n ≤ 2×10⁵,元素 ±10⁶
思路:一次遍历,维护历史最小值,更新最大差值。
代码:
def maxProfit(arr):
if not arr:
return -1
min_price = arr[0]
max_diff = -1
for price in arr[1:]:
if price > min_price:
max_diff = max(max_diff, price - min_price)
min_price = min(min_price, price)
return max_diff
时间复杂度:O(n)
题目 3:n 个顶点构图总数(快速幂)
描述:n 个顶点(labeled),构造无向简单图(无自环、无重边,可不连通)。每对顶点可连边或不连边,求总方案数,对 10⁹+7 取模。
样例:
- n=2 → 2
- n=4 → 64
思路:可能边数为 C(n,2) = n(n-1)/2,每条边 2 种选择 → 答案为 2^{n(n-1)/2} % MOD。n ≤ 10⁹,必须用快速幂。
代码:
MOD = 10**9 + 7
def countGraphs(n):
if n == 1:
return 1
exp = n * (n - 1) // 2
# pow(base, exp, mod)
return pow(2, exp, MOD)
时间复杂度:O(log (n²))
题目 4:合法三元组计数
描述:给定互不相同的整数数组 d 和阈值 t,统计满足 d[a] < d[b] < d[c] 且 d[a]+d[b]+d[c] <= t 的三元组 (a,b,c) 个数(下标不要求顺序,只看值)。
样例:d=[1,2,3,4,5], t=8 → 4(1+2+3=6, 1+2+4=7, 1+2+5=8, 1+3+4=8)
约束:n ≤ 10⁴,d[i] < 10⁹,t < 3×10⁹
思路:先排序(O(n log n))。固定 i < j,双指针找最大的 k 满足 d[i]+d[j]+d[k] <= t 且 d[k] > d[j]。
代码:
def countTriplets(d, t):
d = sorted(d)
n = len(d)
count = 0
for i in range(n-2):
j = i + 1
k = n - 1
while j < k:
if d[i] + d[j] + d[k] <= t:
# 从 j+1 到 k 都满足(已排序)
count += k - j
j += 1
else:
k -= 1
return count
时间复杂度:O(n²)
题目 5:最大技能团队人数(滑动窗口 + 双端队列)
描述:给定技能数组,选最长子数组,使得数组中最大值 – 最小值 ≤ 限定差值(题目中未明确写限定值,常见为给定 limit)。
样例:[4,13,2,3] → 3([4,2,3] 或类似,假设 limit 足够)
约束:n ≤ 10⁵
思路:滑动窗口 + 双端队列维护窗口内最大值和最小值。窗口不满足时左端右移。
代码框架(假设有 limit 参数):
from collections import deque
def maxTeamSize(skills, limit):
n = len(skills)
left = 0
maxq = deque()
minq = deque()
ans = 0
for right in range(n):
# 维护最大值队列(递减)
while maxq and skills[maxq[-1]] <= skills[right]:
maxq.pop()
maxq.append(right)
# 维护最小值队列(递增)
while minq and skills[minq[-1]] >= skills[right]:
minq.pop()
minq.append(right)
# 收缩窗口
while skills[maxq[0]] - skills[minq[0]] > limit:
left += 1
if maxq[0] < left: maxq.popleft()
if minq[0] < left: minq.popleft()
ans = max(ans, right - left + 1)
return ans
时间复杂度:O(n)
题目 6:任务字典序最小重排(奇偶任务可互换)
描述:任务优先级为个位数。奇数=CPU 任务,偶数=IO 任务。只能交换相邻一奇一偶的任务。求可达到的字典序最小的优先级序列。
核心:同奇(或同偶)任务的相对顺序不可改变;奇偶任务可任意穿插(因为可自由交换)。
思路:分别提取奇数序列和偶数序列(保持原相对顺序),然后像归并一样贪心合并,得到字典序最小的交错序列。
代码:
def minLexReorder(tasks):
odds = [x for x in tasks if x % 2 == 1]
evens = [x for x in tasks if x % 2 == 0]
i = j = 0
result = []
while i < len(odds) or j < len(evens):
if i == len(odds):
result.append(evens[j])
j += 1
elif j == len(evens):
result.append(odds[i])
i += 1
elif odds[i] < evens[j]:
result.append(odds[i])
i += 1
else:
result.append(evens[j])
j += 1
return result
写在最后
以上 6 道题目是 IBM 面试中反复出现的高频真题,掌握它们能显著提升通过率。算法面试的核心在于理解本质而非死记硬背,建议大家在练习时注重时间复杂度和边界条件处理。如果你希望获得更多 IBM 真题解析、Java/C++ 版本代码、实时面试助攻,或针对性刷题计划,欢迎联系 ProgramHelp!
ProgramHelp 专注于大厂算法面试辅导,累计帮助数千名同学成功拿到包括 IBM、Google、等 FAANG offer。我们提供:
- 最新大厂真题整理与视频讲解
- 个性化刷题路线规划
- 模拟面试与代码 Review
- OA无痕助攻
- VO实时辅助