一、题意简述
给定一个长度为n的数组a,保证所有元素互不相同。假定a[-1] =a[n]=负无穷,即越界值都是负无穷,求出任意一个峰值的索引下标。
峰值是指:若 下标 i 满足 a[i-1] < a[i] > a[i+1],则 i 就是一个答案。( i 可能会是左边界 0,或者右边界 n)
二、思路分析
要时间复杂度为O(logn),那首先想到二分。因为保证所有元素互不相同,所以我们可以在二分时一直往大的一侧走,直到有效区间内只剩1个元素为止,这个元素就一定是一个峰值。
三、算法逻辑
1. 初始化 i = 0, j = n,有效区间为 [ i, j ),保证区间的两个端点满足: a[i-1] < a[i],a[j-1] > a[j]。
2. while( i < j ) ,每次查找区间中间的元素 a[mid],
if mid比右边元素小,则有效区间变为 [ mid+1, j ) ;
else if mid比左边元素小,则有效区间变为 [ i, mid ) ;
else mid就是峰值,return mid;
3. 跳出循环时,i 一定与 j 相等,这个值就是一个峰值,return i 。
四、c++代码
int findPeakElement(vector<int>& nums) { // write code here int i=0,j=nums.size(); // 保证a[i-1] < a[i], a[j-1]>a[j] while(i<j){ int mid=(i+j)/2; if(mid+1<j && nums[mid]<nums[mid+1]) i=mid+1; //往右边缩小范围 else if(mid>i && nums[mid]<nums[mid-1]) j=mid; //往左边缩小范围 else return mid; } return i; }