zoukankan      html  css  js  c++  java
  • Golang实现二分查找算法

    二分查找范例模板

    1. 寻找目标值

    • 搜索区间(search space): [left, right],可分割为[left, mid - 1]与[mid + 1, right]
    • 循环结束条件: left == right + 1
    • 循环结束时搜索区间取值: [right + 1, right],此时搜索区间为空
    • mid值大于目标值,右边界向左收缩,反之向右扩张
    • 寻得目标值时立即返回该值在数组中的index,反之返回-1
    func binarySearch(arr []int, target int) int{
    	// 搜索区间 [left, right]
    	left := 0 				// 数组左边界的下标index
    	right := len(arr)-1 	// 数组右边界的下标index
    	// 循环条件,左边界小于等于右边界
    	for left <= right{
    		mid := left+(right-left)>>1
    		// mid值大于目标值,右边界向左收缩
    		if arr[mid] > target {
    			right = mid -1
    		}
    		// mid值小于目标值,左边界向右扩张
    		else if arr[mid]<target{
    			left = mid +1
    		}
    		// 符合条件时,随即返回其index
    		else{
    			return mid
    		}
    	}
    	return -1
    }
    

    2. 寻找目标值的左侧边界

    • 搜索区间: [left, right),可分割为[left, mid) 或 [mid + 1, right)
    • 循环结束条件: left == right
    • 循环结束时搜索区间取值: [right, right]
    • 当mid值等于目标值时,无需即时返回该mid,如[1, 2, 2, 2, 3]
    • 此时将右侧边界等于mid,right = mid,继续向左收缩,锁定左侧边界值
    func binarySearch(arr []int, target int) int{
    	// 搜索区间左闭右开,[left, right)
    	left := 0 // 左边界,数组中的最大值元素
    	right := len(arr) 	// 右边界,数组长度
    	// 循环条件,左边界小于右边界
    	for left < right{
    		mid := left+(right-left)>>1
    		// mid值大于目标值,右边界向左收缩
    		if arr[mid] > target {
    			right = mid	//视情况而减1
    		}
    		// mid值小于目标值,左边界向右扩张
    		else if arr[mid]<target{
    			left = mid +1
    		}
    		// 符合条件时不立即返回,继续收缩右侧边界,锁定左侧边界
    		else{
    			right = mid
    		}
    	}
    	return left
    }
    

    3. 寻找目标值的右侧边界

    • 当寻找到目标值时,无需即时返回,而是扩张左侧边界,使得区间向右收缩,锁定右侧边界
    • 循环终止条件: left == right, [right,right]
    • 循环结束时,边界值被更新为left = mid +1,此时left-1的index才可能是target值,所以右侧边界值需减1
    func binarySearch(arr []int, target int) int{
    	// 搜索区间左闭右开,[left, right)
    	left := 0 // 左边界,数组中的最大值元素
    	right := len(arr) 	// 右边界,数组长度
    	// 循环条件,左边界小于右边界
    	for left < right{
    		mid := left+(right-left)>>1
    		// mid值大于目标值,右边界向左收缩
    		if arr[mid] > target {
    			right = mid
    		}
    		// mid值小于目标值,左边界向右扩张
    		else if arr[mid]<target{
    			left = mid +1
    		}
    		// 符合条件时不立即返回,继续扩张左侧下界,锁定右侧边界
    		else{
    			left = mid + 1
    		}
    	}
    	return left-1
    }
    

    参考博文

  • 相关阅读:
    多校第五场 归并排序+暴力矩阵乘+模拟+java大数&amp;记忆化递归
    Cocos2dx-Android 之Makefile通用高级写法
    出现异常 child-&gt;m_pParent == 0
    mybatis一对多关联查询——(九)
    mybatis一对一关联查询——(八)
    mybatis关联查询数据模型分析——(七)
    mybatis动态sql——(六)
    mybatis输入输出映射——(五)
    SqlMapConfig.xml全局配置文件介绍——(四)
    mybatis开发dao的方法——(三)
  • 原文地址:https://www.cnblogs.com/litchi99/p/13504306.html
Copyright © 2011-2022 走看看