首页 > 其他分享 >二分搜索的应用

二分搜索的应用

时间:2023-06-06 15:23:27浏览次数:39  
标签:二分 target nums int mid 搜索 应用 区间 left

目录

简介

应用

应用1:Leetcode

题目

33. 搜索旋转排序数组

分析

方法一

旋转后的数组,就形成了两个有序的子数组。

因为左右两部分子数组都是有序的,所以,在局部查找的时候,依然可以使用二分查找的方式查找。

算法步骤

对于每次找到的区间中点 nums[mid]

  • 如果它在右侧的子区间

    • 如果目标值 target[nums[0], nums[mid]]之间,则移动区间右侧的指针;

    • 否则,就移动区间左侧指针。

  • 如果它在左侧的子区间

    • 如果目标值 target[nums[mid], nums[-1]]之间,则移动区间右侧的指针;

    • 否则,就移动区间左侧指针。

方法二

比较直观的思路是:因为目标值 target 是固定的,所以,我们直接考虑 target 落在左侧子区间,还是右侧子区间。

算法步骤

对于待查找的目标值 target

  • 如果它落在右侧的子区间

    • 如果区间中点nums[mid] 大于目标值 target,或者区间中点 nums[mid] 小于 nums[0],则移动右侧指针;

    • 否则就移动左侧指针。

  • 如果它落在左侧的子区间

    • 如果区间中点nums[mid] 小于目标值 target,或者区间中点 nums[mid] 大于等于 nums[0],则移动左侧指针;

    • 否则就移动右侧指针。

代码实现

方法一

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if not nums:
            return -1

        left, right = 0, len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2

            if nums[mid] == target:
                return mid

            if nums[0] <= nums[mid]:
                if nums[0] <= target < nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            else:
                if nums[mid] < target <= nums[len(nums)-1]:
                    left = mid + 1
                else:
                    right = mid - 1

        return -1

方法二

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

            if target >= nums[0]:
                if nums[mid] > target or nums[mid] < nums[0]:
                    right = mid - 1
                else:
                    left = mid + 1
            else:
                if nums[mid] < target or nums[mid] >= nums[0]:
                    left = mid + 1
                else:
                    right = mid - 1
        return -1

应用2:Leetcode 81. 搜索旋转排序数组 II

题目

81. 搜索旋转排序数组 II

分析

当数组中存在重复元素时,二分查找时,可能会遇到这种情况:

\[nums[left] = nums[mid] = nums[right] \]

此时,无法判断区间应该在左侧,还是右侧缩小。

例如,\(nums = [3,1,2,3,3,3,3,3], target = 2\),第一次二分时,区间中点:\(nums[3] = 3\),区间被分成两个子区间:\(nums[0\cdots2]=[3,1,2]\),\(nums[4\cdots7]=[3,3,3,3]\),此时,区间中点元素\(3\) 与左右边界元素相同。

这种情况,只需要同时缩小左右两侧的边界即可,即左边界加 1,右边界减 1,然后在新的区间上继续二分查找即可。

代码实现

class Solution:
    def search(self, nums: List[int], target: int) -> bool:
        n = len(nums)
        if not nums:
            return False

        if n == 1:
            return nums[0] == target

        left, right = 0, len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return True

            # 左右两侧元素,与区间中点元素相等,则同时移动左右指针
            if nums[left] == nums[mid] and nums[right] == nums[mid]:
                left += 1
                right -= 1
            elif nums[left] <= nums[mid]:
                if nums[left] <= target < nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            else:
                if nums[mid] < target <= nums[-1]:
                    left = mid + 1
                else:
                    right = mid - 1

        return False

标签:二分,target,nums,int,mid,搜索,应用,区间,left
From: https://www.cnblogs.com/larry1024/p/17460083.html

相关文章

  • android应用启动的时候添加图片,并设置跳过按钮
    要在显示图片时添加跳过按钮,可以使用AndroidSDK提供的splashscreen资源文件,并在布局文件中使用。以下是添加跳过按钮的一般步骤:1.在AndroidManifest.xml文件中的应用程序标签中添加以下行:android:splashScreen="res/drawable/splash_screen.png"这将指定使用spla......
  • 应用问题解决-分布式锁(LUA保证删除原子性)
    问题:删除操作缺乏原子性场景1、index1获得锁、执行具体操作、比较lock的uuid值确实和自己生成的uuid是否相等,相等则删除锁。uuid=v1set(lock,uuid)uuid.equals(get("lock"))2、但是index1执行删除前,lock刚好过期时间已经到了,被redis自动释放3、此时index2获取锁,执行具体......
  • 智能呼叫中心——医院随访系统的创新应用
    随访是指医院对曾经接受过治疗的患者进行定期回访,了解他们的病情变化,并提供康复指导。然而,传统的随访方式由于人力和资源的限制,往往难以达到预期的效果。而现在,通过结合互联网、AI等技术,智能化随访系统正在改变这一现状。一、医院随访系统的重要性:持续的病患关怀:随访系统可以帮助医......
  • 实验6 turtle绘图和Python库应用编程体验
    实验任务1task1_1.py源代码1fromturtleimport*23defmove(x,y):4penup()5goto(x,y)6pendown()78defdraw(n,size=100):9foriinrange(n):10fd(size)11left(360/n)1213defmain():14pensize(2)1......
  • 谷歌语音搜索服务Google Now试用效果超Siri
     谷歌语音搜索服务GoogleNow试用效果超Siri导语:美国科技博客BusinessInsider编辑史蒂夫·科瓦奇(SteveKovach)周日撰文称,Android4.1“果冻豆”系统中集成的语音搜索服务GoogleNow比iPhone4S中的Siri功能更强大,但Android系统更新发布速度较慢可能影响GoogleNow的普及。......
  • 分布式搜索elasticsearch集群监控工具bigdesk
    bigdesk是elasticsearch的一个集群监控工具,可以通过它来查看es集群的各种状态,如:cpu、内存使用情况,索引数据、搜索情况,http连接数等。项目git地址: https://github.com/lukas-vlcek/bigdesk。和head一样,它也是个独立的网页程序,使用方式和head一样。插件安装运行......
  • 如何设计React应用程序的样式——比较不同的选项
    样式在创建具有视觉吸引力和用户友好的Web应用程序方面起着至关重要的作用。对于React应用程序,可以通过多种方式来设置组件和UI元素的样式。在本文中,我们将探讨几个流行的选项,包括纯CSS、CSS模块、CSS预处理器、TailwindCSS、CSS-in-JS库(如StyledComponents)以及预构......
  • 克隆和序列化应用(附面试题)
    克隆在开始学习克隆之前,我们先来看看下面的代码,普通的对象复制,存在什么问题?classCloneTest{publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{//等号赋值(基本类型)intnumber=6;intnumber2=number;//......
  • 如何保护Angular应用?这篇文章告诉你答案!
    Angular应用现在很火,但它的安全问题尤为突出。因为开发者不仅要保护应用程序,还要保护到服务器连接。本文将告诉您如何保证Angular应用的安全,以及如何避免应用中的潜在漏洞。PS:给大家推荐一个实用组件~KendoUIforAngular是专业级的AngularUI组件库,不仅是将其他供应商提供的现......
  • 实验6 turtle绘图与python库应用编程体验
    实验任务1task1_11fromturtleimport*23defmoveto(x,y):4'''5画笔移动到坐标(x,y)处6'''7penup()8goto(x,y)9pendown()1011defdraw(n,size=100):12'''13绘制边长为s......