leetcode刷题笔记——Sqrt(x)——binary search二分查找——python

题目:

leetcode刷题笔记——Sqrt(x)——binary search二分查找——python_第1张图片

题目的条件里有说不能用pow()函数和“**”这种现成的表示乘方的函数,不过仔细一想,这一题也不是很难,然后我就快速的写出答案:

class Solution:
    def mySqrt(self, x: int) -> int:
        i=0
        while i*i<=x:
            i+=1
        return i-1

 啥?就这?这也太简单了,然后我提交答案,超越%5的解答,giao,这一题原来大有文章,是我想的太简单了,小丑竟是我自己。我立马跑去看了大佬的解答,醍醐灌顶!!

下面是大佬的解答:
 

class Solution:
    def mySqrt(self, x: int) -> int:
        # binary search
        if x < 2: return x
        left, right = 2, x//2
        while left <= right:
            mid = (left+right)//2
            temp = mid * mid
            if temp < x:
                left = mid + 1
            elif temp > x:
                right = mid - 1
            else:
                return mid
        return right

 看到这有些同学可能就会问了,这么麻烦的代码,有什么值得学习的?如果你也这么想,那你就大错特错了,这个代码里面蕴含了一个常用的基础算法——二分查找

下面是对二分查找的一些介绍:

二分查找有两个要求,一个是数列有序,另一个是数列使用顺序存储结构(比如数组)

假设有这样一个数组

a=[1,3,4,7,9,14,25,36]

要在这个数组中查找x=14这个元素的位置,即下标,我们开始顺序查找

先判断第一个元素a[0]是不是我们要找的x,不是,继续寻找下一个,直到最后,我么一共需要查找6次。

下面我么用二分查找,类似于数学中学到的二分法

那我们先来看看二分法吧:

当我么在数学中,要寻找一个函数的零点位置时,例如函数f(x)=x-4在区间[0,10]上的零点,当然这个零点学过初中的都能一眼望出来,但我们还是来二分以下:

先判断f(0)*f(10),发现<0,说明零点在[0,10]中间,我们二分,取左右边界中间值5;

判断f(0)*f(5)<0,说明零点在[0,5]中间,继续二分,取左右边界中间值2,这里取(0+5)/2的整数部分,因为二分查找也是采用整除的办法,数学中应该取精确值2.5;

判断f(0)*f(2)>0,说明零点不在[0,2]中间,即零点在[2,5]中间;继续二分;

判断f(2)*f(3)>0,说明零点在[3,5]中间;继续二分;

判断f(3)*f(4)=0,说明找到零点,零点为4。

下面来说明一下程序算法中的二分查找

回到之前说的数组:

a=[1,3,4,7,9,14,25,36]

要在这个数组中查找x=14这个元素的位置,即下标,我们开始二分查找:

判断x是否在a[0]和a[7]中间,很明显,a[0]<14

判断x是否在a[0]和[3]中间,程序中则用 if a[mid]>x:来表示,下面会有对应的程序完整代码,可对照观看,发现14>a[3]故x在a[3]和a[7]中间,继续二分,取3和7中间值5;

发现a[5]等于14,返回5,5既是x在数组中的位置。

与先前提到的顺序查找相比,发现只需要3步即可得出答案,效率明显高于顺序查找,尤其在数组长度比较长的时候,二分查找的优势更为明显。

下面时对应的代码:

##查找x在数组a中的位置
a=[1,3,4,7,9,14,25,36]
x=4
left=0
right=len(a)-1
while left<=right:
    mid=(left+right)//2
    if a[mid]>x:
        right=mid-1
    elif a[mid]
对应的输出结果为:2

当把x的值改为14时,输出结果为:5

把x的值改为5,输出结果为:-1     ;说明5不在数组a中。

你可能感兴趣的:(leetcode刷题笔记,算法,二分法,数据结构,python,二分查找)