美文网首页
[Python] 算法心得——二分法

[Python] 算法心得——二分法

作者: 敲代码的密斯想 | 来源:发表于2021-08-10 15:51 被阅读0次

二分查找也称为折半查找,要求查找的对象是顺序排列的(从小到大或者从大到小),其时间复杂度为O(log2n),下面是二分查找最简单的例子:

def binary_search(data_list, val):    
    low = 0                         # 最小数下标    
    high = len(data_list) - 1       # 最大数下标    
    while low <= high:        
        mid = (low + high) // 2     # 中间数下标        
        if data_list[mid] == val:   # 如果中间数下标等于val, 返回            
            return mid        
        elif data_list[mid] > val:  # 如果val在中间数左边, 移动high下标            
            high = mid - 1        
        else:                       # 如果val在中间数右边, 移动low下标            
            low = mid + 1    
    return # val不存在, 返回None

二分法可谓是一种非常基本的查找方法,有很多场景都可以使用到二分法,下面我们来看一下。

1. 有重复元素的二分法查找

给定一个 元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的第一个出现的target,如果目标值存在返回下标,否则返回 -1。

def search(nums , target ):
    res = -1
    if len(nums) < 1:
        return res
    low, high = 0, len(nums) - 1
    while low <= high:
        mid = (low+ high) // 2
        if nums[mid] == target:
            res = mid
            high = mid - 1   # 与传统二分法相比,多了该步骤,因为需要查找到第一次出现target元素的位置
        elif nums[mid] > target:
            high = mid - 1
        else:
            low = mid + 1
    return res
2. 求平方根
def sqrt(self , x ):
        if x < 1:
            return 0
        elif x < 4:
            return 1
        l, h = 1, x // 2
        while l <= h:
            mid = (l + h) // 2
            if mid * mid == x:
                return mid
            elif mid * mid < x:
                l = mid + 1
            else:
                h = mid - 1
        return h
3. 旋转过的有序数组中寻找目标值

给定一个整数数组nums,按升序排序,数组中的元素各不相同。
nums数组在传递给search函数之前,会在预先未知的某个下标 t(0 <= t <= nums.length-1)上进行旋转,让数组变为[nums[t], nums[t+1], ..., nums[nums.length-1], nums[0], nums[1], ..., nums[t-1]]。
比如,数组[0,2,4,6,8,10]在下标3处旋转之后变为[6,8,10,0,2,4]
现在给定一个旋转后的数组nums和一个整数target,请你查找这个数组是不是存在这个target,如果存在,那么返回它的下标,如果不存在,返回-1。

"""
与中间值比较,分前半段有序和后半段有序分别判断。比有序的二分查找多一些判定条件。
1、 要么前半段有序,要么后半段有序。
2、 当前半段有序时:即循环数组中间值比循环数组最左边值大 则 nums[left] <= nums[mid]
当target 比中间值小,比最左值(前半段最小值)大时,肯定在前面部分 则high = mid - 1 。
如果不在前半段,可能在后半段,low = mid + 1。
3、同理后半段也一样。
ps:分前半段有序后半段有序时,当nums[left] <= nums[mid] 则 left到mid有序。
否则 mid到right 有序。
"""
    def search(self , nums , target ):
        # write code here
        l, r = 0, len(nums) - 1
        while l <= r:
            mid = (l + r) // 2
            if target == nums[mid]:
                return mid
            if nums[mid] >= nums[l]:
                if (nums[mid] > target):
                    r = mid - 1
                else:
                    l = mid + 1
            else:
                if nums[mid] < target:# <= nums[r]:
                    l = mid + 1
                else:
                    r = mid - 1
                    
        return -1

相关文章

  • [Python] 算法心得——二分法

    二分查找也称为折半查找,要求查找的对象是顺序排列的(从小到大或者从大到小),其时间复杂度为O(log2n),下面是...

  • 二分法算法

    递归二分法 // 递归算法

  • leetcode涉及的算法复杂度计算

    二分法算法复杂度lognhttps://www.zhihu.com/question/20503898 二分法的复...

  • Search in Rotated Sorted Array

    标签: C++ 算法 LeetCode 数组 困难 二分法 每日算法——leetcode系列 问题 Search...

  • [Python] 算法心得—排序

    1. 冒泡排序 正如其名,不断地将最大/小的数冒泡上来,其时间复杂度为O(N^2),具体实现代码如下: 2. 选择...

  • 射频接收机中的自动增益控制 黄求振

    主要内容 讲述:AGC中的系统控制算法和增益调整算法:二分法,线性算法。AGC_控制算法verilog状态机

  • 算法图解1-2/11

    原书作者 Aditya Bhargava 1 算法简介 1.1 二分法查找 二分法查找,正是猜数字游戏的玩法:A...

  • 前端面试之算法二分法

    使用二分法的前提是,目标数组的元素必须是有序排列的,所以二分法属于有序查找算法 二分法又称为“折半查找”,从数组的...

  • 二分法查找学习笔记

    通过学习二分查找算法,一起学习python。二分法适用于有序的数据查询,且已知顺序。之前听国外的教授讲课,他们拿的...

  • 个人 Python 书单

    入门: Beginning Python 数据结构: Python 数据结构 算法: Python 算法教程

网友评论

      本文标题:[Python] 算法心得——二分法

      本文链接:https://www.haomeiwen.com/subject/zwzxbltx.html