楼主: Falldawn
跳转到指定楼层
上一主题 下一主题
收起左侧

[二分/排序/搜索] 再谈Binary Search 模板while (left < right)的理解

   
🔗
 楼主| Falldawn 2024-5-8 14:09:14 | 只看该作者
全局:
本帖最后由 Falldawn 于 2024-5-7 23:12 编辑
nihonhumita 发表于 2024-5-7 22:50
Thanks. How about leetcode 1539? I found I need to change your template below to work
1) l < r  = ...

1539是比较简单的题目了,难一点的1060,你可以看一下Understanding of Binary Search Template,这里我把题目全部列出来了

LC 1539
这里r 也必须初始化为 n,因为解可能在n
  1. public int findKthPositive(int[] A, int k) {
  2.         if (A == null || A.length == 0 || k <= 0) {
  3.             return -1;
  4.         }
  5.         
  6.         int l = 0, r = A.length, m;
  7.         while (l < r) {
  8.             m = (l + r) / 2;
  9.             if (A[m] - 1 - m < k) {
  10.                 l = m + 1;
  11.             } else {
  12.                 r = m;
  13.             }
  14.         }
  15.         return l + k;
  16.     }
复制代码
LC 1060
Input: nums = [4,7,9,10], k = 3.
We can find the first index where the missing elements >= k. Here we can find index = 2 is the min index where we have missing elements = A[2] - A[0] - (2 - 0) = 3 >= k = 3, then the kth missing number is after A[1] = 7.

Find left bound where A[mid] - A[0] - mid >= k, right must be initialized to n here because the result can lie outside [0, n).
For ex, A[2] - A[0] - (2 - 0) = 1 < k = 3.
Input: nums = [1,2,4], k = 3
Output: 6
  1. public int missingElement(int[] A, int k) {
  2.         int left = 0, right = A.length;
  3.         while (left < right) {
  4.             int mid = left + (right - left) / 2;
  5.             if (A[mid] - A[0] - mid < k) {
  6.                 left = mid + 1;
  7.             } else {
  8.                 right = mid;
  9.             }
  10.         }
  11.         return A[0] + k + left - 1;
  12.     }
复制代码
Input: nums = [4,7,9,10], k = 3.
We can also find the last index where the missing elements < k. Here we can find index = 1 is the max index where we have missing elements = A[1] - A[0] - 1 - 0 = 2 < k = 3, then the kth missing number is after A[1] = 7.
Find right bound where A[mid] - A[0] - mid < k
  1. public int missingElement(int[] A, int k) {
  2.         int left = 0, right = A.length - 1;
  3.         while (left < right) {
  4.             int mid = right - (right - left) / 2;
  5.             if (A[mid] - A[0] - mid < k) {
  6.                 left = mid;
  7.             } else {
  8.                 right = mid - 1;
  9.             }
  10.         }
  11.         return A[0] + k + left;
  12.     }
复制代码
Because finally we need to locate a subarray of two elements where l = r - 1, and the solution will be in this range (A[l], A[r]), which is A[l] + updated k.
  1. public int missingElement(int[] A, int k) {
  2.         int left = 0, right = A.length - 1;
  3.         int missing = A[right] - A[left] - (right - left);
  4.       
  5.         if (k > missing) {
  6.             return A[right] + k - missing;
  7.         }
  8.       
  9.         while (left < right - 1) {
  10.             int mid = left + (right - left) / 2;
  11.             missing = A[mid] - A[left] - (mid - left);            
  12.             if (missing < k) {
  13.                 k -= missing;
  14.                 left = mid;
  15.             }
  16.             else {
  17.                 right = mid;
  18.             }
  19.         }
  20.       
  21.         return A[left] + k;
  22.     }
复制代码
回复

使用道具 举报

🔗
wsha8 2024-6-22 14:24:48 | 只看该作者
全局:
个人经验,写的时候按照stl的lowerbound和upperbound的api设计基本就可以解决几乎所有问题,然后再想办法把lowerbound和upperbound写出来
回复

使用道具 举报

🔗
 楼主| Falldawn 2024-6-23 01:17:42 | 只看该作者
全局:
wsha8 发表于 2024-6-21 23:24
个人经验,写的时候按照stl的lowerbound和upperbound的api设计基本就可以解决几乎所有问题,然后再想办法把 ...

STL?你说的C++嘛?

一开始我写得有点问题,左右边界只要包涵所有可能解即可
回复

使用道具 举报

🔗
wsha8 2024-6-23 06:10:11 来自APP | 只看该作者
全局:
Falldawn 发表于 2024-06-22 10:17:42
STL?你说的C++嘛?

一开始我写得有点问题,左右边界只要包涵所有可能解即可
对,stl有两个二分查找的函数,lower_bound和upper_bound,这两个api设计的是最好也是最标准的
回复

使用道具 举报

🔗
vuuiwo 2024-12-4 00:16:45 | 只看该作者
全局:
OnjoujiToki 发表于 2024-5-3 23:19
比起左右端点这种几何意义上的理解,可以尝试从true/false来进行二分,左闭右开
while loop就可以变成
wh ...

有点没看懂 abs(t-f) 是什么意思,可以再解释一下么
回复

使用道具 举报

🔗
nabulas 2025-1-10 02:30:58 | 只看该作者
全局:
有人有兴趣一起刷题吗朋友?   我在找刷题抱团搭子。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表