编程算法面试题

二分查找:lower_bound、upper_bound和变形

写一个不出bug的二分。lower_bound和upper_bound有什么区别?

为什么面试官会问这道题

"我会二分"的人很多,写不出没off-by-one的很少。面试官专门用这题筛。

如何回答

  1. 1

    经典:精确查找。while(l<=r): mid=(l+r)/2; arr[mid]==t返回;小了l=mid+1,大了r=mid-1。

  2. 2

    lower_bound:第一个>=target的下标。while(l<r): mid=(l+r)/2; arr[mid]<t时l=mid+1,否则r=mid。返回l。

  3. 3

    upper_bound:第一个>target的下标。同lower_bound改成<=。

  4. 4

    二分答案:答案对某谓词单调时(K个工人能否做完?)。对K二分。

  5. 5

    旋转有序数组:mid和l(或r)比,判断哪半有序,再看target是否在那半内。

参考回答示例

我背两个模板。"精确查找":`while(l<=r){ m=l+(r-l)/2; 相等返回m; 小了l=m+1; 大了r=m-1; }`——闭区间,l>r没找到。"第一个满足谓词":`while(l<r){ m=(l+r)/2; 满足r=m; 不满足l=m+1; }`——l==r就是答案。lower_bound就是谓词arr[m]>=target;upper_bound就是arr[m]>target。"二分答案"是同一个模板把谓词换成可行性判断——D天装运的capacity、minimize max之类。旋转数组分支:l..m或m..r哪半有序就在它范围里判target。

实用技巧

  • 用`mid=l+(r-l)/2`而不是`(l+r)/2`——大下标溢出。

  • 开闭区间先定好就一以贯之——混用是#1 bug来源。

  • 即答侠给了两个模板+断言——粘贴改编。

常见问题

为什么lower_bound用l<r而精确查找用l<=r?

不变量不同。精确查找失败时两边都缩;lower_bound里r始终是"候选答案",不能剔除。

无序数组能二分吗?

除非搜索域上有单调性。"二分答案"就是把无序问题转化成可二分的典型招。

面试时担心忘词?即答侠实时助你

即答侠 AI 实时监听面试对话,自动识别问题并即时生成回答建议——无感辅助,让你从容应对每一道题。

免费试用即答侠