在最初的二分查找中,我们将一组数据按大小排序,然后根据arr[mid]与要查找的k的大小比较,从而每次去掉一半的数字,使时间复杂度简化为O(logN)。
排序本质上是让数据的单调性统一,变为单增或单减,而不是混合的。
下面我们看一道好题:
寻找峰值_牛客题霸_牛客网
找出两个山峰,山峰是一个比两边都大的数字,也就是这组数据的极大值(极值点是坐标)
//处理两个边界if(numsLen==1||nums[0]>nums[1]){return 0;}if(nums[numsLen-1]>nums[numsLen-2]){return numsLen-1;}
数据的首尾比较好判断,且题目中规定越界的部分为负无穷,我们可以先将这两部分判断好。
确保首尾均不是极值后,我们可以得到下图。
两边向下的箭头:代表靠近首尾边界时,均为单调递减 。即left 然后我们对中间的值与其附近的值进行比较。这里我假设arr[mid] 然而,对于左半边的部分,起始和终止均为单增,单调性一致,无法确定是否存在峰值。 left=mid+1,因为mid不可能是峰值。right=mid,因为此时mid可能是峰值。 二分查找的时间复杂度为O(logN),是一种高效的查找方式,在做相关题目,要注意找到单调性的规律,满足什么条件时单调性改变,产生极值,是解题的关键,找到单调性的规律后,就可以一次排查掉一半数据了,还有就是注意leftint findPeakElement(int* nums, int numsLen )
{//处理两个边界if(numsLen==1||nums[0]>nums[1]){return 0;}if(nums[numsLen-1]>nums[numsLen-2]){return numsLen-1;}int i=0;int left=0;int right=numsLen-1;int mid=0;while(left