rust lower_bound以及upper_bound实现


勘误一下,upper_bound的作用是找到第一个 > target的元素,而不是以前认为的小于或者等于target的最后一个元素。
lower_bound和upper_bound是c++里的二分查找函数,lower_bound找的是集合中第一个大于等于target的下标; upper_bound则相反,找的是第一个大于target的元素的下标。

实现的话也是用二分法,区别在于当找到等于的元素以后,不能马上退出循环,而是需要在另外一半的元素中继续搜索,直到搜索区间的长度收缩为1。有一个比较坑的地方在于Rust只能用usize,也就是u64作为数组下标,所以这里的left <= right有可能因为right - 1溢出,而无法退出循环。需要额外判断right = 0的情况。

let lower_bound = |nums: &Vec<i32>, target: i32| {
  let (mut left, mut right) = (0, nums.len() - 1);
  let mut res = right;
  if nums.len() == 0 || nums[res] < target {
      return usize::MAX;
  }
  while left <= right {
      let mid = (left + right) / 2;
      if nums[mid] == target {
          res = usize::min(res, mid);
      }
      if nums[mid] >= target {
          if mid == 0 {
              break;
          }
          right = mid - 1;
      } else {
          left = mid + 1;
      }
  }
  res
};

Author: 蒋璋
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source 蒋璋 !