题目重点:求ratings/prices最大的商品,使用交叉乘避免浮点并列误判。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练prices正整数、ratings整数1..5,两数组非空等长;返回0起始index,同ratio取最早。价格0拒绝,不定义无限比值。
解题路线
- 初始化best0,依次比较ratings[i]×prices[best]与ratings[best]×prices[i]。分母正所以交叉乘不等号方向不变。
- 严格大于才更新,等于不动自然保留最早index。不能>=更新,那会返回最后并列。
- 不做float division,极大价格附近比值可能舍入相等;Python任意精度乘法精确比较,固定宽度语言要扩类型/检查乘积溢出。
- 只按题目定义,不加质量/库存因素;非法数据拒绝,空列表没有有效index。独立Fraction oracle可检查精确有理数排行。
手动走一遍
prices[2,4,3]、ratings[1,2,2]前两ratio均0.5,第三2/3最高返回2;只前两返回0。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def best_value(prices,ratings):
"""Positive integer prices, integer ratings 1..5, tie earliest 0-based index."""
if not prices or len(prices)!=len(ratings):raise ValueError('nonempty equal lengths')
if any(not isinstance(p,int) or p<=0 for p in prices) or any(not isinstance(r,int) or not 1<=r<=5 for r in ratings):raise ValueError('invalid price or rating')
best=0
for i in range(1,len(prices)):
if ratings[i]*prices[best]>ratings[best]*prices[i]:best=i
return best
复杂度
O(N)次比较/O(1)索引状态,按固定大小整数计;b位大整数乘法成本依b增长。无需sort全部商品O(N log N)。
易错点与追问
容易失分的边界
- >=更新覆盖最早并列。
- float舍入或固定宽度乘积溢出改变排行。
继续深挖
- 定点小数价格先统一单位整数,精度必须明确。
- 返回所有并列index需要集合或第二次扫描,计输出空间。
