Python 每日一练 二分查找 搜索旋转排序数组 详解

简介: Python 每日一练 二分查找 搜索旋转排序数组 详解

大一在读 大数据管理与应用专业 欢迎交流


备战蓝桥杯 倒计时71天


目前主要学习Python算法与数据结构 今日主题:二分查找


算法人算法魂 算法题让我们敢于挑战自己做意想不到的事情


如果还没接触过二分查找的可以看一下小郑上一篇博客保证入门简简单单(有模板)(属于优化版 适用很多场景 但今天这道题用起来就相形见绌了)


今天这个二分写法与上面的模板有所不同 是最基本的写法👇很简单对吧

#核心框架
while a<=b:
    mid=(a+b)//2
    if nums[mid]==target:
        return mid
    elif nums[mid]>target:
        b=mid-1
    else:
        a=mid+1

👇👇现在来让我们试试手  

问题描述:

cfde4ac523c844dda336eb9347849aae.png

如果你觉得比较难?先看看这种方法  

Python 自带函数解法:index函数用法传送门

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


cfad0ec270f74da1889b77ad64814603.png

二分查找法:


你肯定会说 ''这是无序的!!   二分查找只能用于有序数组 ''


对的 二分查找的确只能用于有序数组


但是审题后我们会发现:nums是由升序数组旋转得到(旋转规则根据题意可知)


先说结论 旋转后的数组 指针定在任意一个位置 那么两段序列中至少有一段是升序的

                                                   (我知道你有点不完全相信我!!)


但事实就是如此:


edc3509c9917497fa040f406f347c168.jpg


第一行是未旋转的升序序列 第二行是旋转后的


当指针指向中间 有两段升序序列


当指针指向右边(2)2到n-1是升序的 n到2不是升序的 因此有一段升序序列


当指针指向左边(n+1)n到n+1是升序的 n+1到n-1不是升序的 因此有一段升序序列


所以说明上面的结论是正确的 (或许你可能觉得我这样证明还不严谨)


那下面给出严格证明:假设数列元素>2个 (一个旋转了还是本身)


设k为分界点 下标0-k升序 下标k-len(nums)-1升序 对数列进行旋转


旋转后 指针指向k 旋转数列有两段升序序列 指向<k的位置 k左半边是有序


指向>k的位置 k右半边是有序   证明完毕


代码设计思路:拿到旋转后的数组  划分区域:有序的 无序的


对有序的二分查找 如果找到 大功告成


如果找不到 返回第一步 再次对第一轮的无序区域划分有序区域和无序区域


发现了吗?这其实就是一个递归的过程 因此我们设置两个指针l和r 用来递归每一次的无序区间 😀


class Solution:
    def search(self, nums: List[int], target: int) -> int:
        def Binary_search(l,r,target):
            if l==r and nums[l]!=target:return -1  
            mid=(l+r)//2#至少有一段是完全递增的
            if nums[mid]<nums[l]:#有序区间在右,对其对分查找
                a,b=mid,r
                while a<=b:
                    middle=(a+b)//2
                    if nums[middle]==target:
                        return middle
                    elif nums[middle]>target:
                        b=middle-1
                    else:
                        a=middle+1
                return Binary_search(l,mid-1,target)#如果右有序区间没找到 去找左无序区间
            else:#有序区间在左,对其对分查找
                a,b=l,mid
                while a<=b:
                    middle=(a+b)//2
                    if nums[middle]==target:
                        return middle
                    elif nums[middle]>target:
                        b=middle-1
                    else:
                        a=middle+1
                return Binary_search(mid+1,r,target)#如果左有序区间没找到 去找右无序区间
        return Binary_search(0,len(nums)-1,target)

3e71a42cf92e44778b428e61c7070793.png

好啦 今天的每日一练就到这里 祝大家新年快乐😀和小郑一起加油


相关文章
|
20天前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
103 63
|
1月前
|
搜索推荐 Python
快速排序的 Python 实践:从原理到优化,打造你的排序利器!
本文介绍了 Python 中的快速排序算法,从基本原理、实现代码到优化方法进行了详细探讨。快速排序采用分治策略,通过选择基准元素将数组分为两部分,递归排序。文章还对比了快速排序与冒泡排序的性能,展示了优化前后快速排序的差异。通过这些分析,帮助读者理解快速排序的优势及优化的重要性,从而在实际应用中选择合适的排序算法和优化策略,提升程序性能。
37 1
|
2月前
|
机器学习/深度学习 并行计算 大数据
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧2
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧
90 10
|
2月前
|
Python
Python对PDF文件页面的旋转和切割
Python对PDF文件页面的旋转和切割
48 3
|
2月前
|
索引 Python
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧1
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧
111 4
|
2月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
78 0
|
3月前
|
Python
Python中几种lambda排序方法
【9月更文挑战第7天】在Python中,`lambda`表达式常用于配合排序函数,实现灵活的数据排序。对于基本列表,可以直接使用`sorted()`进行升序或降序排序;处理复杂对象如字典列表时,通过`lambda`指定键值进行排序;同样地,`lambda`也适用于根据元组的不同位置元素来进行排序。
|
3月前
|
数据处理 Python
python遍历文件夹所有文件按什么排序
python遍历文件夹所有文件按什么排序
29 0
|
3月前
|
数据处理 Python
Python遍历文件夹所有文件并按指定排序
Python遍历文件夹所有文件并按指定排序
83 0
|
4月前
|
Python
Python魔法:用一行代码实现数据排序
【8月更文挑战第31天】忘掉传统多行排序代码,本文揭秘如何使用一行Python代码快速对数据进行排序,同时深入探讨背后的原理和性能考量。