【算法学习】二分搜索五种写法

145 阅读1分钟

经典写法

需要注意的三点:

  1. 循环退出条件,注意是 low <= high,⽽不是 low < high。
  2. mid 的取值,mid := low + (high-low)>>1
  3. low 和 high 的更新。low = mid + 1,high = mid - 1。
func binarySearchMatrix(nums []int, target int) int {
  low, high := 0, len(nums)-1
  for low <= high {
    mid := low + (high-low)>>1
    if nums[mid] == target {
      return mid
    } else if nums[mid] > target {
      high = mid - 1
    } else {
      low = mid + 1    }
  }
  return -1
}

二分扩展写法

查找第⼀个与 target 相等的元素,时间复杂度 O(logn)

func searchFirstEqualElement(nums []int, target int) int {
  low, high := 0, len(nums)-1
  for low <= high {
    mid := low + ((high - low) >> 1)
    if nums[mid] > target {
      high = mid - 1
    } else if nums[mid] < target {
      low = mid + 1
    } else {
      if (mid == 0) || (nums[mid-1] != target) { // 找到第⼀个与 target 相等的元素
        return mid
      }
      high = mid - 1
    }
  }
  return -1
}
	

查找最后⼀个与 target 相等的元素,时间复杂度 O(logn)

func searchLastEqualElement(nums []int, target int) int {
  low, high := 0, len(nums)-1
  for low <= high {
    mid := low + ((high - low) >> 1)
    if nums[mid] > target {
      high = mid - 1
    } else if nums[mid] < target {
      low = mid + 1
    } else {
      if (mid == len(nums)-1) || (nums[mid+1] != target) { // 找到最后⼀个与 
target 相等的元素
        return mid
      }
      low = mid + 1
    }
  }
  return -1}

查找第⼀个⼤于等于 target 的元素,时间复杂度 O(logn)

func searchFirstGreaterElement(nums []int, target int) int {
  low, high := 0, len(nums)-1
  for low <= high {
    mid := low + ((high - low) >> 1)
    if nums[mid] >= target {
      if (mid == 0) || (nums[mid-1] < target) { // 找到第⼀个⼤于等于 target 的元return mid
      }
      high = mid - 1
    } else {
      low = mid + 1
    }
  }
  return -1
}

查找最后⼀个⼩于等于 target 的元素,时间复杂度 O(logn)

func searchLastLessElement(nums []int, target int) int {
  low, high := 0, len(nums)-1
  for low <= high {
    mid := low + ((high - low) >> 1)
    if nums[mid] <= target {
      if (mid == len(nums)-1) || (nums[mid+1] > target) { // 找到最后⼀个⼩于等于 
target 的元素
        return mid
      }
      low = mid + 1
    } else {
      high = mid - 1
    }
  }
  return -1
}