本文主要是介绍每周一算法之二分查找(Kotlin描述),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
简述: 从这篇文章起就会开启另一个系列就是上篇文章中提到的每周学习一个基本算法,会结合LeetCode上题目来做分析。解题的语言一般是Kotlin或Java. 如果涉及到一些有关Kotlin的知识点也会做一些介绍。如果平时就养成学习数据结构算法以及刷题的习惯,不管今后你是面试(愿从此再也不是面试造火箭平时拧螺丝了)或在实际上工作中都会对你有很大帮助。这也是这个系列文章的目的。
一、时间复杂度
最坏时间复杂度 O(log n)
最优时间复杂度 O(1)
平均时间复杂度 O(log n)
二、基本思想
在一个有序的列表中,要查找的数与列表中间的位置相比,若相等说明找到了,若要查找的数大于列表中间的数,说明要查找的数可能在有序列表的后半部分;若要查找的数小于列表中间的数,说明要查找的数可能在有序列表的前半部分;然后类似上述操作缩短查找范围,最后直到查找到最后一个数,如果不等于要查找的数,那么查找范围就为空。
三、算法步骤
给定一个包含n个带值的元素数组或序列A[0], … A[n-1],使A[0] <= … <= A[n-1],以及目标值Target.
- 1、令 low = 0, high = n - 1
- 2、若low > high, 则表示查找失败结束
- 3、令mid(中间值元素)为 (low + high) / 2的值向下取整 (注意: 在具体实现中为了防止溢出,一般会采用 low + (high - low) / 2的值向下取整 或者直接采用位运算的移位运算来实现除2的操作。这个后面会有具体题目来说明)
- 4、若Target > A[mid], 令 low = mid + 1 (说明要查找的值在序列或数组后半部分(除去自身),移动low游标,缩小查找范围),并回到步骤2
- 5、如果Target < A[mid], 令 high = mid - 1 (说明要查找的值在序列或数组前半部分(除去自身),移动high游标,缩小查找范围),并回到步骤2
- 6、如果Target == A[mid], 查找成功并结束,返回mid下标值。
四、算法过程演示
五、代码实现(Kotlin语言描述)
二分查找算法主要有两种实现方式,一种是循环递推的方式,另一种则是递归的方式
- 1、 循环递推实现方式
- 2、递归实现方式
六、为什么Java中mid = (low + high) / 2方式会溢出
相信刷过LeetCode题目的小伙伴们可能会在刷二分查找的题目过程会遇到超过时间限制的错误
不知道大家有没有去分析过为什么会得到超时啊,我都用了二分查找了时间复杂度都变成 O(log n) 呢,为啥还会超时呢。实际上是int数据类型溢出导致出现负数,使得代码进入了死循环,然后导致超时,最后OJ给你个超出时间错误。
- 1、出现问题的原因
我们可以确定 low 和 high 都是非负数,那么也就是二进制表示的最高位符号位是0,并且low 和 high 都是31位二进制的整数
假设下面这种场景:
high = 0100 0000 0000 0000 0000 000
这篇关于每周一算法之二分查找(Kotlin描述)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!