zoukankan      html  css  js  c++  java
  • 二分查找

    一、寻找一个数

    1.左闭右闭

    func search(nums []int, target int) int {
        lf, rt := 0, len(nums)-1
        for lf <= rt{
            mid := lf + (rt-lf)/2
            if nums[mid] < target{
                lf = mid + 1
            }else if nums[mid] > target{
                rt = mid - 1
            }else if nums[mid] == target{
                return mid
            }
        }
        return -1
    }
    

    2.左闭右开

    func search(nums []int, target int) int {
        lf, rt := 0, len(nums) // 左闭右开
        // 不用等于为了避免lf=rt=len(nums)越界
        for lf < rt{ 
            mid := lf + (rt-lf)/2
            if nums[mid] < target{
                lf = mid + 1 
            }else if nums[mid] > target{
                rt = mid // 区别
            }else if nums[mid] == target{
                return mid 
            }
        }
        // lf < len(nums)避免越界 如1,2,3,4中找8,此时lf=4越界
        // nums[lf] == target lf==right这种情况漏了
        if lf < len(nums) && nums[lf] == target{ 
            return lf
        }
        return -1
    }
    

    二、寻找边界

    常用左闭右开方法,该方法更好理解,不容易出错!

    1.左闭右开

    // 左边界 左闭右开
    func leftBound(nums []int, target int) int {
    	if len(nums) == 0 {
    		return -1
    	}
    	lf, rt := 0, len(nums) // 左闭右开
    	for lf < rt {
    		mid := lf + (rt-lf)/2
    		if nums[mid] < target {
    			lf = mid + 1
    		} else if nums[mid] > target {
    			rt = mid
    		} else if nums[mid] == target {
    			rt = mid
    		}
    	}
    	// target比nums中的所有数都要大的时候 lf >= len(nums)
    	// 如果nums中不存在与target相等的数 但有小于target的数时会出现lf < len(nums) && nums[lf] != target
    	if lf < len(nums) && nums[lf] == target {
    		return lf
    	}
    	return -1
    }
    
    // 右边界 左闭右开
    func rightBound(nums []int, target int) int {
    	if len(nums) == 0 {
    		return -1
    	}
    	lf, rt := 0, len(nums) // 左闭右开
    	for lf < rt {
    		mid := lf + (rt-lf)/2
    		if nums[mid] < target {
    			lf = mid + 1
    		} else if nums[mid] > target {
    			rt = mid
    		} else if nums[mid] == target {
    			lf = mid + 1
    		}
    	}
    	// target比nums中的左右数都要小的时候 lf-1 < 0
    	// 如果nums中不存在与target相等的数 但有小于target的数时会出现lf-1 >= 0 && nums[lf-1] != target
    	// 因为nums[mid] == target时lf=mid+1,所以结束循环时lf=右边界+1
    	if lf-1 >= 0 && nums[lf-1] == target {
    		return lf - 1 
    	}
    	return -1
    }
    

    2.左闭右闭

    越界现象

    // 寻找左边界 左闭右闭
    func leftBound(nums []int, target int) int {
    	lf, rt, mid := 0, len(nums)-1, 0
    	for lf <= rt {
    		mid = (lf + rt) >> 1
    		if target < nums[mid] {
    			rt = mid - 1
    		} else if target > nums[mid] {
    			lf = mid + 1
    		} else {
    			rt = mid - 1 // 右边界等于中间值--
    		}
    	}
    	if lf >= len(nums) || nums[lf] != target{
    	    return -1
    	}
    	return lf
    }
    
    // 寻找右边界 左闭右闭
    func rightBound(nums []int, target int) int {
    	lf, rt, mid := 0, len(nums)-1, 0
    	for lf <= rt {
    		mid = (lf + rt) >> 1
    		if target < nums[mid] {
    			rt = mid - 1
    		} else if target > nums[mid] {
    			lf = mid + 1
    		} else {
    			lf = mid + 1 // 左边界等于中间值++
    		}
    	}
    	if rt >= 0 && nums[rt] == target {
    		return rt
    	}
    	return -1
    }
    
    

    参考链接

  • 相关阅读:
    scala学习笔记(8)
    mysql复习(1)基本CRUD操作
    sql获得表主键信息
    C#缓存-依赖 CacheHelper
    MVC过滤器实现用户登录验证
    MVC过滤器
    MVC页面和表单
    在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token
    MVC DbContext
    MVC数据注解
  • 原文地址:https://www.cnblogs.com/lsyy2020/p/14826584.html
Copyright © 2011-2022 走看看