SWE Intern · OA REST API Coding

Rippling OA Costliest Chocolate:分页 API、价格重量比与平局

逐页读取目标品牌所有商品和变体,以交叉乘法比较 price/weight,同分取较小 productNumber。

题目重点:逐页读取目标品牌所有商品和变体,以交叉乘法比较 price/weight,同分取较小 productNumber。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练 `fetch_page(page)` 返回 `{data:[{brand,productNumber,prices,weights}],total_pages}`;price/weight 为非负/正整数且同一商品两数组一一对应。该 JSON 是训练契约,不声称原 OA API 格式。
  • 没有匹配的有效商品返回 None;brand 大小写敏感。若 price/weight 用小数需先转统一最小单位或 Decimal,不能直接做二进制浮点精确交叉比较。

解题路线

  1. 从第一页读取 total_pages,逐页拉完,不可只看第一页;每个目标品牌 product 的同下标 price/weight 组成一个变体。
  2. 全局保留 winner、最高比率分子/分母;新比率 p/w 与 best_p/best_w 用 p×best_w 和 best_p×w 比较,平局按更小 productNumber。
  3. 扫描所有目标品牌变体,不能先为每个 product 随意挑一个不同口径的价格;同一 product 的任一变体最高可使它获胜。
  4. 独立用 Fraction 对 3,500 组分页/商品组合求最大比率及最小 ID,覆盖空页、重复比率和多变体。生产 API 再加超时、429 退避、页数上限和稳定游标防漏页。

手动走一遍

A 品牌 product 8 有 10/2=5,product 3 有 15/3=5,两者同分选 3。B 品牌即便有 100/1 也不参加。若第二页还有 A 商品 21/3=7,则最终改选第二页。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def costliest_chocolate(fetch_page, brand: str) -> int | None:
    """Training API: page dict {data:[products], total_pages:int}; positive weights."""
    winner: int | None = None
    best_num = best_den = 0
    page = 1
    while True:
        payload = fetch_page(page)
        total_pages = payload["total_pages"]
        if not isinstance(total_pages, int) or total_pages < page:
            raise ValueError("invalid pagination")
        for product in payload["data"]:
            if product["brand"] != brand:
                continue
            number = product["productNumber"]
            prices, weights = product["prices"], product["weights"]
            if len(prices) != len(weights):
                raise ValueError("mismatched variants")
            for price, weight in zip(prices, weights):
                if weight <= 0 or price < 0:
                    raise ValueError("invalid price or weight")
                if winner is None or price * best_den > best_num * weight or (
                    price * best_den == best_num * weight and number < winner
                ):
                    winner, best_num, best_den = number, price, weight
        if page == total_pages:
            return winner
        page += 1

复杂度

P 页、总 R 个商品、总 V 个目标品牌变体,扫描 O(P+R+V) 时间;若分页逐页处理且不存全部结果,额外空间 O(单页最大商品数)。API 网络延迟/限流往往主导总时间。

易错点与追问

容易失分的边界

  • 只请求首页。
  • 用浮点近似比率处理平局。
  • 不核对 prices/weights 长度一致或重量为零。
  • 对同品牌只看第一款变体。
  • 平局选较大 ID 或随输入顺序返回。

继续深挖

  • 分页数据在扫描中变化导致重复/漏项怎么办?
  • 商品价格用小数货币如何做精确比较?
  • 如果 API 只给 next cursor,该如何循环?
  • 如何处理 429 与部分页失败而不误报结果?
✓已复制微信号!