二分查找
二分查找也称折半查找(Binary Search),它是一种效率较高得查找方法。一般都是要求线性表有序,然后二分查找的时间复杂度为O(logN)。
不一样的二分
如果数组无序,难道就不能用二分查找了吗?答案是否定的,即使一个数组无序,也可以用二分查找来找。下面我就用两个例子来给你们上一课(膨胀了我,哈哈~~~)
例子1(旋转数组):
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
即使数组无序,但是我们还是可以使用二分查找来找出最小值。因为旋转数组部分有序,利用二分查找还是很容易查找到最小值
代码:
1 | public class Solution { |
通过:
可能有人会觉得,即使无序可以使用二分查找,但是你这个旋转数组也是部分有序,所以可以使用二分查找。接下来我再讲解一道题来证明给你看——查找局部最小值。
例子2(查找局部最小值)
定义局部最小的概念。arr数组长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小;如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;如果0<i<N-1,既有arr[i]<arr[i-1],又有arr[i]<arr[i+1],那么arr[i]是局部最小。 给定无序数组arr,已知arr中任意两个相邻的数都不相等。写一个函数,只需返回arr中任意一个局部最小出现的位置即可。
思路:
- 先查找arr[0]和arr[N-1],即第一个数和最后一个数是不是局部最小,如果是,直接返回这个数即可。
- 如果arr[0]>arr[1],arr[N-1]>arr[N-2],那么此时的情况就是这样的:
代码:
1 | /** |
运行结果:
总结
看了上面的两个例子,是不是颠覆了你对二分查找的认知。哈哈。不是说一定要有序才能用二分查找,只要你确定了某一部分一定有你要找的,你就可以二分下去找。