整数二分

66 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情

整数二分

注意:有单调性一定可以进行二分,没有单调性的题目也可以进行二分,二分的本质不是单调性

一般应用于无非下面这四种情况: 1:找大于等于数的第一个位置 (满足某个条件的第一个数) ->左边界点 2:找小于等于数的最后一个数 (满足某个条件的最后一个数)->右边界点 3.查找最大值 (满足该边界的右边界) 4.查找最小值 (满足该边界的左边界)

二分的本质:寻找性质的边界

只要我们的区间可以找到这样一个性质,就可以用二分把边界点二分出来

image-20221027105749001

边界可以是红色点,也可以是绿色点,想要二分出灰色点和绿色点就是两个不同的模板


如果此时我们想要二分出红色点:

首先找到中间位置mid,判断中间位置是否满足红色部分性质,

  • 如果满足,说明mid就在红色区间位置,此时就要去[mid,right]区间找答案, 注意:此时要包含mid位置,因为mid位置是满足红色位置的,可能mid位置就是答案

    • 将[left,right]区间更新为:[mid,right]区间
  • 如果不满足: 说明此时mid在绿色区间内, 此时就要去[left,mid-1]区间找, 此时不包含mid位置,因为mid位置此时是不满足红色部分性质

    • 将[left,right]位置更新为:[left,mid-1]区间

image-20221027110442997


上面求中间值mid存在问题:当left=right-1的时候,此时mid = (left+right)/2 ,向下取整 mid = left ,此时如果满足条件,true: 再使left = mid时,还是[left,right]区间,就陷入了死循环


解决办法: mid = (left + right + 1) /2 ,此时当left = right-1的时候,此时如果满足条件,true: 再使left = mid时,此时就跳出循环了!

image-20221027111209449


如果我们想二分出绿色区间的边界点

首先找到中间值,判断中间值是否满足绿色的性质

  • 如果满足:说明此时mid在绿色区间位置, 此时就要去[left,mid]去寻找, 要包含mid位置!因为mid位置满足性质

    • 把[left,right]区间更新成[left,mid]区间
  • 如果不满足:说明此时mid在红色区间位置,此时就要去[mid+1,right]之间找,此时不包含mid,因为mid不满足性质

    • 把[left,right]区间更新成[mid+1,right]区间

image-20221027111618264


总结:如果更新方式是right = mid ,求中间值就不需要+1,如果是left = mid,此时求中间值就需要+1