二分思想:区间[l, r]内的数存在分段性质,最常见的是单调性,即mid左边的元素比mid大,右边的小,或 反之。二分本质上是每次缩减搜索空间,寻找满足性质的元素。 1)如果要寻找绿色的中间端点,if mid是绿色性质,r = mid , [l , r] ->[l, mid] if mid是红色性质,l = mid + 1 [l , r] ->[mid + 1, r] 同理如果要找红色的中间端点,if mid 是红色的 [l , r] ->[mid, r],如果mid是绿色, [l , r] ->[l, mid - 1] 1.两大原则: 1)每次都要缩减搜索区域。 2)每次缩减不能排除潜在答案。 2. 查找准确值 l <= r,l = mid + 1, r = m- 1; 3.查找模糊值 l < r,l = mid , r = mid - 1;或l = mid + 1, r = mid. 例1.要寻找不减数组中k的第一次出现位置(假设k至少出现一次)。判断条件是 num[mid] < target ,l =mid + 1, 否则r = mid。根据原则2,要找到第一次出现的位置,则需要往前搜索,mid之前可能出现过,也可能没出现过,则往前搜索不能排除掉mid,则r = mid. 例2.要寻找不减数组中k的最后一次出现位置,判断条件是 num[mid] > target ,r =mid - 1, 否则l = mid.往右搜索需要包含mid。 4.万用型 l < r,l = mid, r = mid; 5.二分查找出现死循环的原因。 1) 若循环条件为l < r,满足条件的l = mid,不满足的r = mid - 1,mid = l + (r - l) / 2,最后一次搜索区间为[l, l + 1],mid = l,此时若任然满足条件,则l=mid,相当于把l赋值给l,则搜索区间不会变化,下一次依旧满足条件,陷入死循环,所以为了避免死循环,如果执行l = mid,当只有两个元素时,mid要指向右边元素,实现方法mid = l + (r - l + 1) / 2. 2)同理,如果操作的是r = mid,为了避免只有两个元素时死循环,下一次循环mid要指向左边的元素,所以mid = l + (r - l) / 2。