LeetCode Task04 数组数组二分查找 0704二分查找 0069Sqrt(x)


一、0704二分查找

题目链接
题目描述:

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

示例:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

思路:这道题很基础,直接按照二分查找的算法实现即可。
设定左右节点为数组两端,即:
l e f t = 0 , r i g h t = l e n ( n u m s ) − 1 left = 0,right = len(nums) - 1 left=0right=len(nums)1
分别代表待查找区间为:
[ l e f t , r i g h t ] ( 左 闭 右 闭 ) 。 [left, right](左闭右闭)。 [left,right]
取两个节点中心位置 m i d mid mid,先比较中心位置值 n u m s [ m i d ] nums[mid] nums[mid] 与目标值 t a r g e t target target的大小。
如果中心位置值 n u m s [ m i d ] nums[mid] nums[mid]与目标值 t a r g e t target target相等,则返回中心位置。
如果中心位置值 n u m s [ m i d ] nums[mid] nums[mid]小于目标值 t a r g e t target target,则将左节点设置为 m i d + 1 mid + 1 mid+1,然后继续在右区间 [ m i d + 1 , r i g h t ] [mid + 1, right] [mid+1,right]搜索。
如果中心位置值 n u m s [ m i d ] nums[mid] nums[mid]大于目标值 t a r g e t target target,则将右节点设置为 m i d − 1 mid - 1 mid1,然后继续在左区间 [ l e f t , m i d − 1 ] [left, mid - 1] [left,mid1]搜索。


代码如下:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid-1
            else:
                left = mid + 1
        return -1

运行结果如下:
在这里插入图片描述
官方代码:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = (high - low) // 2 + low
            num = nums[mid]
            if num == target:
                return mid
            elif num > target:
                high = mid - 1
            else:
                low = mid + 1
        return -1

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-search/solution/er-fen-cha-zhao-by-leetcode-solution-f0xw/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

感觉二分查找的思路就挺清晰的,实现出来大同小异。

在这里插入图片描述
观察可发现,在判断那里先赋值再做比较,可以减少一次nums索引的时间,加快执行用时。

二、Sqrt(x)

题目链接
题目描述:

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例:
输入:x = 4
输出:2

思路:这道题如果要用二分查找的思想来解决的话,可以将查找范围限定在 [ 0 , x ] [0,x] [0,x]之间,当 m i d 2 < x mid^2<x mid2<x时,更新范围集合为 [ 0 , m i d − 1 ] [0,mid-1] [0,mid1];当 m i d 2 > x mid^2>x mid2>x时,更新范围集合为 [ m i d + 1 , x ] [mid+1,x] [mid+1,x]
在计算的过程中,使用变量ans将目前满足条件的最大整数值保留下来。

代码如下:

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

在这里插入图片描述
使用作弊代码,发现快了挺多:

class Solution:
    def mySqrt(self, x: int) -> int:
        import math
        return int(math.sqrt(x))

在这里插入图片描述
使用牛顿迭代的方法:

class Solution:
    def mySqrt(self, x: int) -> int:
        val = x
        error = x-0
        while error >= 1:
            last = val
            val = (val+x/val)/2
            error = abs(val-last)
        return int(val)

在这里插入图片描述

官方提供的使用二分查找思想的代码如下:

class Solution:
    def mySqrt(self, x: int) -> int:
        l, r, ans = 0, x, -1
        while l <= r:
            mid = (l + r) // 2
            if mid * mid <= x:
                ans = mid
                l = mid + 1
            else:
                r = mid - 1
        return ans

在这里插入图片描述
很好奇为什么官方的快这么多,修改原代码,发现直接求幂运算比两个mid相乘慢,即mid**2改成mid*mid。修改后结果如下。
在这里插入图片描述
一种基于地址移位的快速sqrt算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值