一、 題目
峰值元素的定義是比鄰居元素都大的元素。
給定一個數組,其中array[n] != array[n + 1],找出峰值元素並返回它的索引。但是其中可能含有多個峰值,不過返回其中的一個就可以了,可以假設num[-1] = num[n] = 負無窮大。
例如,[1,2,3,1],3就是峰值,返回索引2。
二、 分析
方法一:www.Bkjia.com
暴力,其實這個方法還可以吧,如果是一般的對稱情況,例如[1,2,3,4,3,2,1],也就是遍歷一半,而且根據這種思路,方法很多,主要是變形,不過主題思想還是一樣的。
class Solution { public: int findPeakElement(const vector&num) { int n = num.size(); for(int i=1; i < n; i++){ if(num[i] < num[i-1]) return i-1; } return n -1; } };
class Solution { public: int findPeakElement(const vector&num) { int n = num.size(); for(int i = 0; i < n; i++){ if((i == 0 || num[i] > num[i - 1]) && (i == n-1 || num[i] > num[i + 1])) return i; } return -1; } };
class Solution { public: int findPeakElement(const vector&num) { int n = num.size(); for(int i=1; i < n; i++){ if(num[i] > num[i-1] && (num[i] > num[i+1] || i == n-1)) return i; } return 0; } };
方法二:
二分法,其實也就是和數組中找出一個元素的情況差不多,不過是判斷的條件不一樣罷了。還有這種思路又有兩種方法,一是一直二分二分直到left == right;另一種是找出符合的值就直接返回。
如下:
class Solution { public: int findPeakElement(const vector&num) { int left = 0, right = num.size() - 1; int mid; while(left <= right){ mid = (left + right)/2; if((mid == 0 ||num[mid] > num[mid - 1]) && (num[mid] > num[mid + 1] || mid == num.size() -1)) return mid; else if( mid > 0 && num[mid-1] > num[mid]) right = mid - 1; else left = mid + 1; } return 0; } };
class Solution { public: int findPeakElement(const vector&num) { int left = 0, right = num.size() - 1; int mid; while(left <= right){ if(left == right) return left; mid = (left + right)/2; if(num[mid] < num[mid + 1]) left = mid + 1; else right = mid; } } };