[Alg]旋转有序数组的中二分查找

根据中位数与旋转点相对位置查找

切分数组查找

 

给定一个没有重复元素的旋转数组(它对应的原数组是有序的),求给定元素在旋转数组内的下标(不存在的返回-1),时间复杂度为logN。
如[4,5,6,7,0,1,2]就是一个旋转数组:

  • 查找3,返回-1;
  • 查找0,返回4;

根据中位数与旋转点相对位置查找

从中位数与旋转点的相对位置看,可以有:

  • 旋转点在中位数右侧:中位数及其左侧元素全部为升序,且小于中位数;
  • 旋转点与中位数相同或在中位数左侧:中位数及其右侧元素全部升序,且大于中位数;
def searchInShiftArray(ary:list, ele:int)->int:
    def bisearch(ary, start, end):
        if start>end:
            return -1
        mid = (start+end)//2
        if ary[mid] == ele:
            return mid

        if ary[mid]>ele:
            return bisearch(ary, start, mid-1)
        else: 
            return bisearch(ary, mid+1, end)


    def search(ary, start, end):
        if start>end:
            return -1
        mid = (start+end)//2
        if ary[mid] == ele:
            return mid

        if ary[mid]<ele:            
            if ary[start]>ary[mid]: # mid在旋转点后,
                if ary[end]>=ele:
                    return bisearch(ary, mid+1, end)
                return search(ary, start, mid-1)
            # mid在旋转点前
            return search(ary, mid+1, end)
        else: # ary[mid]>ele
            if ary[start]>ary[mid]: # mid在旋转点后,
                return search(ary, start, mid-1)
            # mid在旋转点前
            if ary[start]<=ele:
                return bisearch(ary, start, mid-1)
            return search(ary, mid+1, end)

    return search(ary, 0, len(ary)-1) 

切分数组查找

查找有序数组最方便的方式是二分查找,而旋转数组也可以看作是由‘旋转点’(数组中最小元素)切分的两个有序数组。可先找到旋转点,然后分别在两个有序数组中查找即可。

查找旋转点:

def findPivotPoint(ary:list)->tuple:
    if ary[0]<ary[len(ary)-1]:
        return (False, 0, ary[0])

    def findPoint(ary:list, start, end):
        if start == end:
            return start

        mid = (start+end)//2
        if ary[mid]>ary[end]:
            return findPoint(ary, mid+1, end)
        else: #
            if ary[mid]<ary[mid-1]:
                return mid
            else:
                return findPoint(ary, start, mid-1)

    index = findPoint(ary, 0, len(ary)-1)
    return (True, index, ary[index])
相关推荐
市面上能下载的《算法导论》文版都没有目录(标签) 阅读极不方便 翻阅困难 本人 crocostone 亲自手动制作了完整的标签 包括章 节 小节的标签 在Acrobat 7 0和9 0版本和FoxitReader 4 2版本均能打开 而且 我精心调整了文档的大小 打开或点击标签的时候 默认就是最适合阅读 眼睛最舒服的文档大小 无需再调整大小 本人亲自制作 在CSDN上奉献 欢迎使用 有了目录(标签) 学习效率真的可以提高一大截啊 注意本压缩包使用WinRAR分卷压缩 4个部分都下载后才能解压 为什么要分卷:整个文件有130MB crocostone的上传权限不够 所以只能分卷压缩 已经测试:这4个压缩包 使用WinRAR 7zip Haozip都能正确解压 内容: 1 全世界唯一带“完整”目录的《算法导论》第二版文版 2 目前能找到的多个版本的习题答案和代码 有Java实现的 C++实现的 官方的 非官方的 教参 考试题答案等等 3 讲义 4 算法导论第二版最清晰的英文版 文字和伪代码可以拷出来 书籍介绍: 《算法导论》(Introduction to Algorithms)原书第二版 Thomas H Cormen(科曼) Charles E Leiserson Ronald L Rivest Clifford Stein著 南京大学潘金贵 顾铁成 李成法 叶懋等译 机械工业出版社 2006 本书简称CLRS 麻省理工学院教材 全世界最广泛使用的算法超经典书籍 学习编程必看之书 作者之一的Rivest就是RSA算法发明者的R 2002年图灵奖得主 算法是程序员必练内功 此书主要讨论算法 数据结构方面的内容稍少 文翻译质量不错 ################################################### 本人的电脑以前没有WinRAR 而是一直使用7zip 但是7zip制作的zip分卷压缩格式竟然与WinRAR不兼容 导致前面发的资源 用WinRAR的网友说无法解压 在这里表示抱歉 使用7zip或Haozip的人都解压成功了 这次发的资源 4个压缩包 使用WinRAR 7zip Haozip都能正确解压 请CSDN网友 下载完 评论的同时 要点击评论框上方的五角星(共5个五角星) 这样你的被扣的积分就可以返还 还会加一分 如果只评论 不点击小五角星 积分不会返还 一定要先下载完 再评论 如果先评论后下载 或者在下载的过程评论 积分同样不会返还 数据结构教材 我强烈推荐Sartaj Sahni著《数据结构算法与应用 C++语言描述》 这是一部难得的好书 作者循序渐进 娓娓道来 每一种数据结构和算法都给出了详细的实现代码和运行结果 而且代码质量极高 甚至可以直接照搬到商业软件开发 此书的算法部分也很精到 比算法导论更容易学习和入门 Sartaj Sahni《数据结构算法与应用 C++语言描述》全集 包含英文图书 代码 习题答案 演示动画 都是我亲自从此书的官方网站下载并汇总的 绝对权威 算法和数据结构是计算机的绝对核心技术 学好核心技术 既为了自己 也为了天空不落下别国的炸弹 别国的天空落下我们的炸弹 ">市面上能下载的《算法导论》文版都没有目录(标签) 阅读极不方便 翻阅困难 本人 crocostone 亲自手动制作了完整的标签 包括章 节 小节的标签 在Acrobat 7 0和9 0版本和FoxitReader 4 2版本均能打开 而且 我精心调整 [更多]
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页